I get current UTC time to be used internally from a Windows service application using GetSystemTime API. But I'm curious, is the time returned by that API Daylight-saving independent?
PS. Let me explain what I mean. Say, I call GetSystemTime and it returns 01:59:00 AM on the day when the Daylight-saving should take effect at 2 AM. I then call this API again in 2 minutes later (after the Daylight-saving change.) Will the second result be 2 minutes apart from the 1st result, or will Daylight-saving change be reflected in it?
UTC is ... UTC
Daylight saving
UTC does not change with a change of seasons, but
local time or civil time may change if a time zone jurisdiction
observes daylight saving time (summer time). For example, UTC is five
hours ahead of (that is, later in the day than) local time on the east
coast of the United States during winter, but four hours ahead while
daylight saving is observed there.
Your local time is an offset, and daylight savings (which is a local phenomenon) only changes the offset.
There is no such thing as daylight savings time in UTC.
However, there are occasional leap seconds. The last leap second was added on June 30, 2012 at at 23:59:60 UTC. Time at the end of that day went from 23:59:59 to 23:59:60 before going to 00:00:00 July 31, 2012.
Use something such as Atomic Time if you want a leap-second free time standard.
Related
I'm attempting to modify the creation dates of files to the date they were released. I'm first converting a string such as "2 April 2005" into a std::tm. I then create a SYSTEMTIME as follows:
std::tm dt = from_string("2 April 2005");
SYSTEMTIME st { 0 };
st.wYear = dt.tm_year + 1900; // dt is years from 1900
st.wMonth = dt.tm_mon + 1; // dt is month index 0
st.wDay = dt.tm_mday;
st.wHour = 6; // FILETIME is based on UTC, which is 6 hours ahead
Afterwards I convert the SYSTEMTIME to a FILETIME and use that to apply the changes.
This sets the file time to 2 April 2005 12:00:00 AM which is correct. However, videos after April 2nd were being set to 1:00:00 AM and sure enough, daylight savings happened on April 3rd 2005.
How can I determine if a certain date is before or after daylight savings so I can adjust st.wHour accordingly? The goal is to have all times set to 12:00:00 AM. Preferably this would work on dates dating back to the 60s as well as current.
I tried using TIME_ZONE_INFORMATION and GetTimeZoneInformation but I only get back TIME_ZONE_ID_STANDARD.
A few things:
SYSTEMTIME is just a plain structure. It has separate fields for year, month, day-of-week, day (of month), hour, minute, second and millisecond. It is not either UTC or local time, or anything else by itself. That doesn't come into consideration until you pass it into a function.
FILETIME is another plain structure. It represents the number of 100-nanosecond intervals since midnight of 1601-01-01. Much of the docs would make you think it is always in UTC, but there are functions like FileTimeToLocalFileTime that disprove that. Thus, like SYSTEMTIME, it is up to each individual function to decide how to interpret it.
The SystemTimeToFileTime function accepts a pointer to a SYSTEMTIME that is interpreted as UTC, and returns a pointer to a FILETIME that is also in terms of UTC. There is no local time zone involved.
Don't try to adjust for local time yourself (st.wHour = 6 in your code). The hour will need to vary depending both on time zone and on DST.
You didn't see any response from GetTimeZoneInformation other than TIME_ZONE_STANDARD, because that tells you what is currently in effect - which is disconnected from the dates you might be working with.
You shouldn't be trying to figure out how to adjust for DST on your own. DST is not universally applicable, and it's not always one hour offset. Instead, use a function that converts from the time zone you care about to UTC.
Ultimately it sounds like you are asking about how to set the file time to midnight of the local time zone on a particular date. Thus, I suggest you go through these steps:
Construct a SYSTEMTIME with the date you care about and the time components set to zeros (the default).
Get the local time zone using the GetDynamicTimeZoneInformation function. You want the "dynamic" version such that any historical differences in rules for standard time and DST that Windows knows about are taken into consideration, rather than just the current set of rules.
Pass those two values to the TzSpecificLocalTimeToSystemTimeEx function. It will interpret the input time as being in the input time zone (which was the system's local time zone). The result is a FILETIME that is in terms of UTC.
Pass that value to SetFileTime, which expects the input in terms of UTC.
Also, keep in mind that not all file systems track file times in the same way:
NTFS stores the actual UTC time, so you can move files between computers and the timestamp represents the same point in Universal Time even if the computers have different time zone settings.
FAT and its variants store local time. So when you call SetFileTime, Windows translates from UTC to the local time zone and writes the result. If you then open the file on a system with a different time zone, the date will be interpreted in that time zone, resulting in a different UTC time. (This is often seen on USB sticks, memory cards, etc. when moving files from cameras to computers.)
Lastly, you said:
... Preferably this would work on dates dating back to the 60s as well as current.
Unfortunately, Windows time zones do not track historical dates that far. Microsoft's time zone policy is to track time zone and DST rules for 2010 and forward for all populated places on Earth. Although, several time zones track some historical changes from before 2010 as artifacts from before this policy was formalized. (They are accurate within a given zone, just not uniform in starting years across all zones).
If historical dates are significant to your application, you'll need a very different approach - one that doesn't use the Windows time zone data, but instead uses the IANA time zone database. (More on these in the timezone tag wiki.) Here are some ideas you could explore:
The ICU project has time zone support and a C implementation. It's a bit heavy for this one purpose, but good if you are using it for other localization aspects of an application.
Howard Hinnant (who commented on the question above) has an excellent Date library with IANA time zone support.
It might be possible to get what you need from the Windows.Globalization.Calendar UWP class. I haven't tested to see if it will use historical rules from IANA data or if it uses the Windows data. (If I get a chance to check, I'll come back and update this answer.)
Keep in mind that the IANA database only guarantees from 1970 forward. You said you needed from 1960, and though there are some zones with data for that (and some much older), there is no guarantee of correctness in that period.
I’m using Rails 4.2.3. I want to take a time in milliseconds (a duration, not a UTC time) and convert it into hours, minutes and seconds. I’m trying this
Time.at(time_in_ms).utc.strftime("%H:%M:%S")
but this doesn’t seem to be working. For instance, in my POstGresql database, I have this amount of milliseconds
3601000
and the above is producing
16:16:40
even though it should produce something like “1:00:01” (one hour and one second). What is the proper way to convert time in milliseconds to a nicely formatted hours, minutes, and seconds?
Time.at() expects a time in seconds after a certain epoch - 1 Jan 1970 00:00:00 UTC - so your code needs to divide the ms figure by 1000 first:
Time.at(time_in_ms/1000).utc.strftime("%H:%M:%S")
EDIT: I just rechecked the Ruby docs: the below rider is incorrect! The passed-in number of seconds is assumed to be in UTC, so at() does the calculation THEN factors in the UTC offset. The above .utc undoes that factoring, and is required.
Of course, the problem with that code then becomes your current time zone. Say you're at UTC-5 (New York time): Time.at(3601000/1000) becomes "01:00:01" local time. Converting it to UTC would subtract five hours from the hour figure, making it "20:00:01". So remove your .utc conversion too:
Time.at(time_in_ms/1000).strftime("%H:%M:%S")
The time_orign_epoch,should be 1970-01-01 00:00:00,why i am getting 5:30 more?
time_origin_epoch = datetime.datetime.fromtimestamp(0)
print time_origin_epoch
1970-01-01 05:30:00
It's because you live in India!
How did I know that?
Well, a timestamp of 0 means 1970-01-01 00:00:00 UTC. Since your output shows 05:30:00, your time zone is UTC+05:30. And India is one of the few places in the world with a timezone offset which is not a whole number of hours.
When you construct a datetime in Python using fromtimestamp(), the default is to use your local timezone for the conversion. This corresponds to calling the classic C function localtime() rather than gmtime().
Running your code gives me a result that is five hours behind what it should be. This is consistent with the fact that I am in EST and am five hours behind UTC.
If you are simply looking to confirm correct output, then check your time zone, I would guess you are somewhere in Eastern Asia. However, if you need a zeroes value produced by the program itself, try resetting your timezone to UTC from the program, and running that snippet again.
From this answer:
If you are using Unix, you can use time.tzset to change the process's local timezone:
import os
import time
os.environ['TZ'] = tz
time.tzset()
You could then convert the datetime strings to NumPy datetime64's using
def using_tzset(date_strings, tz):
os.environ['TZ'] = tz
time.tzset()
return np.array(date_strings, dtype='datetime64[ns]')
I am trying to add Events To FaceBook with the Time Zone option enabled. I am trying to add Events in UK with time zone as "Europe/London" . This is what I am noticing.
When I send the following Start & End times
[start_time] => 2014-08-24T20:00:00+0100
[end_time] => 2014-08-24T22:00:00+0100
I get the time as
[When]
Sunday, August 24, 2014
[Time]
8:00pm until 10:00pm
when viewed from FaceBook Site. My time zone is set to London which is UTC. But when I send an event in November,
[start_time] => 2014-11-24T20:00:00+0000
[end_time] => 2014-11-24T22:00:00+0000
it is getting displayed as
[When]
Monday, November 24, 2014
[Time]
9:00pm until 11:00pm
Is this an expected behavior. Will the time be adjusted and 8 PM will show correctly on Nov 24th?
Thanks
Lynn
One small correction. You said:
My time zone is set to London which is UTC
The Europe/London zone is UTC+00:00 in the winter, which is commonly called GMT. In the summer it switches to UTC+01:00. which is commonly called BST. It wouldn't be accurate to say that London is UTC. I think you knew this already, I'm just stating it here for others.
Unfortunately, the behavior you describe is expected for Facebook. It comes down to the fact that Facebook doesn't know you are in Europe/London. It simply gets your current time zone offset from JavaScript's new Date().getTimezoneOffset() when you log in. Since it's currently UTC+01:00, that's the offset that is applied to the events when you view the page as a user. It makes a flawed assumption that the offset will not change, or that you won't be looking at future event times until after the next transition.
The Facebook Graph API represents this in the user object. It has a timezone property that is just a number. I guess the Facebook developers haven't read the timezone tag wiki where I make clear that "Time Zone != Offset".
Will the time be adjusted and 8 PM will show correctly on Nov 24th?
Yes. It will show the correct time as soon as the user logs in after the next switch from BST to GMT, which is on October 27th this year.
What is the difference between gmtime() and localtime() ?
My requirement:
I need to display the time as per the time zone of my place.
I have a time in POSIX(UTC) format in seconds. i have time zone offset(between UTC and my current place) in seconds.
I either add or subtract the time zone offset.
After this i still have the time in POSIX format.
In order to convert it to human time, should I use gmtime() or localtime(). this is because i need the date too.
Please clarify.
Thanks!
You shouldn't provide the time zone offset yourself, but rather a real time zone specification via the environment. Then, localtime will give you the localized time. (gmtime always gives you UTC.) Suppose your code looks like
struct tm time_buffer, *localtime;
localtime = localtime_r(timep, &time_buffer);
printf("The hour is %i\n", localtime->tm_hour);
, then you call your program via:
$ TZ=Europe/Berlin my-program
and get the local hour of Berlin, correctly adjusted for daylight saving time.
If you absolutely need to provide a timezone yourself, read man tzset.
gmtime is UTC—coordinated universal time. It is always the
same, everywhere. localtime is an interpretation of the local time,
as determined by the time zone and whether summer time is in effect or
not. The time zone will be determined by the environment variable TZ,
which the user should have set to his local timezone; if this variable
is not set, an implementation defined default is used: typically the
timezone where the machine is located.