问题
While writing some unit tests on a Julian Day calculator, I found that dates prior to 2nd December 1847 were being initialised incorrectly by NSDate. They appear to have 75 seconds added on. I haven't been able to find anything pointing to that date (which is well after the Gregorian calendar cutoff). Is it a bug or is there a historic calendar adjustment that I've not come across?
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *dateComps = [NSDateComponents new];
dateComps.year = 1847;
dateComps.month = 12;
dateComps.day = 1;
NSDate *d1 = [cal dateFromComponents:dateComps];
NSLog(@"d1 = %@", d1);
dateComps = [NSDateComponents new];
dateComps.year = 1847;
dateComps.month = 12;
dateComps.day = 2;
NSDate *d2 = [cal dateFromComponents:dateComps];
NSLog(@"d2 = %@", d2);
}
return 0;
}
Output:
d1 = 1847-12-01 00:01:15 +0000
d2 = 1847-12-02 00:00:00 +0000
回答1:
According to http://www.timeanddate.com/worldclock/clockchange.html?n=136&year=1847 there was a time shift forward of 75 seconds at that time.
In London, when local time was about to reach 12:00:00 AM on Wednesday December 1, 1847, clocks were advanced to Wednesday, December 1, 1847 12:01:15 AM.
回答2:
In response to the post by Richard Krajunus, here is some additional information from the zoneinfo database used by most computers to track these kinds of changes:
# From Paul Eggert (1993-11-18):
#
# Howse writes that Britain was the first country to use standard time.
# The railways cared most about the inconsistencies of local mean time,
# and it was they who forced a uniform time on the country.
# The original idea was credited to Dr. William Hyde Wollaston (1766-1828)
# and was popularized by Abraham Follett Osler (1808-1903).
# The first railway to adopt London time was the Great Western Railway
# in November 1840; other railways followed suit, and by 1847 most
# (though not all) railways used London time. On 1847-09-22 the
# Railway Clearing House, an industry standards body, recommended that GMT be
# adopted at all stations as soon as the General Post Office permitted it.
# The transition occurred on 12-01 for the L&NW, the Caledonian,
# and presumably other railways; the January 1848 Bradshaw's lists many
# railways as using GMT. By 1855 the vast majority of public
# clocks in Britain were set to GMT (though some, like the great clock
# on Tom Tower at Christ Church, Oxford, were fitted with two minute hands,
# one for local time and one for GMT). The last major holdout was the legal
# system, which stubbornly stuck to local time for many years, leading
# to oddities like polls opening at 08:13 and closing at 16:13.
# The legal system finally switched to GMT when the Statutes (Definition
# of Time) Act took effect; it received the Royal Assent on 1880-08-02.
#
# In the tables below, we condense this complicated story into a single
# transition date for London, namely 1847-12-01. We don't know as much
# about Dublin, so we use 1880-08-02, the legal transition time.
Sorry I couldn't respond using a comment in that thread; StackOverflow does not deem me worthy of that yet.
回答3:
Is it a bug or is there a historic calendar adjustment that I've not come across?
There have been a number of times the calendar was ... fixed in the past.
Check the "adoption" sections of the wikipedia articles for Julian and Gregorian calendars.
The NSDate instance should always be showing the correct date for whatever timezone it was initialized with, however.
回答4:
NSDateComponents are using your local time zone. Try setting the timeZone to UTC?
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *dateComps = [NSDateComponents new];
dateComps.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
dateComps.year = 1847;
dateComps.month = 12;
dateComps.day = 1;
NSDate *d1 = [cal dateFromComponents:dateComps];
NSLog(@"d1 = %@", d1);
dateComps = [NSDateComponents new];
dateComps.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"UTC"];
dateComps.year = 1847;
dateComps.month = 12;
dateComps.day = 2;
NSDate *d2 = [cal dateFromComponents:dateComps];
NSLog(@"d2 = %@", d2);
[19875:60b] d1 = 1847-12-01 00:00:00 +0000
[19875:60b] d2 = 1847-12-02 00:00:00 +0000
来源:https://stackoverflow.com/questions/21921589/where-is-the-extra-75-seconds-coming-from