function [leaps,ver] = leapseconds()
% LEAPSECONDS List all leap seconds for use by datetimes.
%   T = LEAPSECONDS() returns a timetable containing a list of leap seconds
%   supported by DATETIME, including the date on which they occurred, their
%   sign, and the cumulative adjustment.
%
%   [T,VER] = LEAPSECONDS() also returns the IERS Bulletin C version number
%   supported by DATETIME. See
%   
%       https://www.iers.org/IERS/EN/Publications/Bulletins/bulletins.htm
%   
%   for details.
%
%   See also DATETIME, datetime.TimeZone.

%   Copyright 2019 The MathWorks, Inc.

[leaps,type,ver] = matlab.internal.datetime.getLeapSecondsList();

% Account for both positive and negative leap seconds, although in practice a
% negative leap second has never (as of 2019) occurred. There's some belief that
% "double leap seconds" can occur, but this is apparently incorrect, see e.g.
% https://www.ucolick.org/~sla/leapsecs/timescales.html#UTC
Date = datetime(1970,1,leaps,'Format','dd-MMM-yyyy'); % unzoned
Type = categorical(type,[+1 -1],["+" "-"]);
CumulativeAdjustment = seconds(cumsum(type));
leaps = timetable(Date,Type,CumulativeAdjustment);

% The list of leap seconds can also be generated by brute force: Add 86400s to each
% 30-Jun and 31-Dec from 1970 until now. If there's a positive leap second, that
% puts us at 23:59:60, if there's a negative leap second it puts us at 00:00:01
% of the next day, and if there's no leap second it puts us at 00:00:00 of the
% next day.
%years = (1970:datetime().Year+1)';
%d = datetime(repmat(years,1,12),repmat(1:12,length(years),1),1,'TimeZone','UTCLeapSeconds');
%dend = dateshift(d,'end','month') + hours(24);
%leaps = sort(dend(dend.Second ~= 0));
%date = dateshift(leaps,'start','day'); date.TimeZone = ''; date.Format = 'dd-MMM-yyyy';
%sign = (leaps.Second == 60)*2 - 1;
% In theory, leap seconds can occur at the end of _any_ month, although in
% practice they've only ever happened in June or December.

