It feels to me like everywhere I've seen time related algorithms in programming, GMT was the base time. For example, I was told to always store time in a DB in GMT+00 so that time zone changes don't disrupt anything.
Am I right that GMT seems to be the base time zone in software development?
If so, why not UTC? Why is it not common to say "UTC+01" instead of "GMT+01" considering that even Unix timestamps are defined from UTC (http://en.wikipedia.org/wiki/Unix_time)
GMT and UTC are the same time. UNIX time is based off of UTC, so you might find that more on UNIX and *nix systems.
UTC is also more closely tracked as an official time (i.e. is more closely in line with "true" time based off of earth's rotation). But unless your software needs to-the-second calculations, it shouldn't make a difference whether you use GMT or UTC.
Although, you might consider which to display to users. One format may be more familiar than another. I would typically go with UTC for global applications, and GMT for European or UK-based applications.
This accepted response is actually wrong. First they are not the same by any means. Second UTC is NOT more closely in line with "true" time based off of earth's rotation, is exactly the opposite. UTC is more precise in terms of 'time' measure. Each second last the same since is based on atomic time and the precision is increidble hight (it would take 30 thousand years to offset one second).
GMT instead tracks earth rotation, since this is not always the same (the earth rotation is slowing down) each second differs. Of course, differs in a really small ammount of time. But for cientific purposes, is a lot more accurate UTC than GMT.
This is the reason why UTC changes +2 seconds every 4/5 years (since earth rotation is slower each second it takes to rotate has to be bigger than UTC), so it follows GMT earth rotation time by less than a second of difference.
I thought it would be fun to discover what IANA timezones are currently using the abbreviation "GMT", both now and 6 months from now (to catch those currently on daylight saving time).
Using this free, open source C++11/14 library, I wrote this program:
#include "tz.h"
#include <string>
#include <iostream>
#include <vector>
template <class Duration>
std::vector<date::zoned_time<std::common_type_t<Duration, std::chrono::seconds>>>
find_by_abbrev(date::sys_time<Duration> tp, const std::string& abbrev)
{
using namespace std::chrono;
using namespace date;
std::vector<zoned_time<std::common_type_t<Duration, seconds>>> results;
auto& db = get_tzdb();
for (auto& z : db.zones)
{
if (z.get_info(tp).abbrev == abbrev)
results.push_back(make_zoned(&z, tp));
}
return results;
}
int
main()
{
using namespace std::chrono;
using namespace date;
auto now = system_clock::now();
auto v = find_by_abbrev(now, "GMT");
for (auto const& x : v)
std::cout << format("%F %H:%M:%S %Z %z", x) << " "
<< x.get_time_zone()->name() << '\n';
std::cout << '\n';
v = find_by_abbrev(now + months{6}, "GMT");
for (auto const& x : v)
std::cout << format("%F %H:%M:%S %Z %z", x) << " "
<< x.get_time_zone()->name() << '\n';
}
This searches the planet for all timezones that are currently using "GMT", both now, and 6 months from now, and prints them out:
2016-06-18 01:00:25.632773 GMT +0000 Africa/Abidjan
2016-06-18 01:00:25.632773 GMT +0000 Africa/Accra
2016-06-18 01:00:25.632773 GMT +0000 Africa/Bissau
2016-06-18 01:00:25.632773 GMT +0000 Africa/Monrovia
2016-06-18 01:00:25.632773 GMT +0000 America/Danmarkshavn
2016-06-18 01:00:25.632773 GMT +0000 Atlantic/Reykjavik
2016-06-18 01:00:25.632773 GMT +0000 Etc/GMT
2016-12-17 15:55:01.632773 GMT +0000 Africa/Abidjan
2016-12-17 15:55:01.632773 GMT +0000 Africa/Accra
2016-12-17 15:55:01.632773 GMT +0000 Africa/Bissau
2016-12-17 15:55:01.632773 GMT +0000 Africa/Monrovia
2016-12-17 15:55:01.632773 GMT +0000 America/Danmarkshavn
2016-12-17 15:55:01.632773 GMT +0000 Atlantic/Reykjavik
2016-12-17 15:55:01.632773 GMT +0000 Etc/GMT
2016-12-17 15:55:01.632773 GMT +0000 Europe/Dublin
2016-12-17 15:55:01.632773 GMT +0000 Europe/London
I was gratified to see that in all cases the UTC offset was +0000. You never know with politicians and timezones. Some legislative body could easily proclaim "Green Mountain Time" (and just might tomorrow).
GMT and UTC are not the same thing. Read https://en.wikipedia.org/wiki/Greenwich_Mean_Time and the link in there to UTC for the distinctions.
Some computer users are confused by the fact that until Windows 7, no Microsoft operating system fully supported UTC, and thus kept labeling the international time reference as GMT.
The key issue is how Windows reads and sets the BIOS clock. Windows XP can't handle setting the BIOS clock to UTC, so you must set the BIOX clock to local time, and then rely on Windows keeping track of the difference.
As of Windows 7, Windows can handle setting the BIOS clock to UTC and does all of the calculations (mostly?) consistent with UTC, so Microsoft decided to switch the label from GMT to UTC.
See:
https://superuser.com/questions/185773/does-windows-7-support-utc-as-bios-time
I would say that it is because most people are used to GMT. If you're going to display information to a person, specifically time, you would want a format they can easily understand. Using GMT saves you the extra steps of converting to UTC and back.
Related
I need to get the UTC offset for a location. I am getting trouble with the inconsistency of the results from different values. All I need to get are values in the format +HHMM (e.g., +0100 for "Europe/Rome").
func main() {
loc, _:= time.LoadLocation("Asia/Kathmandu")
offset, others:= time.Now().In(loc).Zone()
fmt.Println(offset, others)
}
Playground
What I get:
"Asia/Kathmandu": +0545 (suitable)
"Asia/Ho_Chi_Minh": +07 (should be +0700)
"America/Phoenix": MST (should be -0700)
"Europe/Rome": CET (should be +0100)
Reference Timezone country names
The Zone() method you're using is working exactly as advertized.
Zone computes the time zone in effect at time t, returning the abbreviated name of the zone (such as "CET") and its offset in seconds east of UTC.
A better approach for you would be to use the Format method. Something like:
zone := time.Now().In(loc).Format("-0700")
Of course, be aware: Even this won't be 100% consistent, due to daylight savings time.
I'm trying to parse a string into time with a user-specific timezone location -
// error handling skipped for brevity
loc, _ := time.LoadLocation("Asia/Kolkata")
now, _ := time.ParseInLocation("15:04", "10:10", loc)
fmt.Println("Location : ", loc, " Time : ", now)
The output I get on my system is - Location : Asia/Kolkata Time : 0000-01-01 10:10:00 +0553 HMT
Where did this HMT time zone come from?
If instead of parsing the time I use now := time.Now().In(loc), the timezone printed is correct - IST. Am I doing something wrong with timezone parsng or is my system timezone database faulty?
This may be a relic of the fact that your year for now is 0000, while time.Now() returns the current time. Timezones are weird, and certain locations haven't always used the same timezone. This is an excerpt from the IANA Time Zone Database:
# Zone NAME GMTOFF RULES FORMAT [UNTIL]
Zone Asia/Kolkata 5:53:28 - LMT 1854 Jun 28 # Kolkata
5:53:20 - HMT 1870 # Howrah Mean Time?
5:21:10 - MMT 1906 Jan 1 # Madras local time
5:30 - IST 1941 Oct
5:30 1:00 +0630 1942 May 15
5:30 - IST 1942 Sep
5:30 1:00 +0630 1945 Oct 15
5:30 - IST
If I am interpreting this correctly, it seems HMT was used from 1854 until 1870—I'm not exactly sure why this would cause it to be used for year 0000, which would seem to fall under LMT, but it's possible the Go database is slightly different (or it's possible that I'm misinterpreting the database). If you're concerned about the correct timezone being used for historical dates (like 0000) I'm not sure I can give a great answer, however for anything recent IST should be correctly used.
I have a table keyed by time, e.g.
time | valA | valB
---- | ---- | ----
09:00| 1.4 | 1.2
09:05| 1.5 | 1.4
09:10| 1.5 | 1.4
I want to store this in a data structure and query values as of arbitrary times. E.g.
asof 09:01, valA = 1.4
asof 09:06, valB = 1.4
asof 09:14, valA = 1.5
What is the best way of structuring this in c++11? Which std::chrono datatype should I use to represent my times. How can I develop a solution that supports time zones? E.g. the times listed in my table may be in US/Central time and I may want to query using Australia/Sydney based times.
To support local times in different time zones with <chrono> I recommend Howard Hinnant's free, open-source time zone library. This library is built on top of <chrono>, and uses the IANA time zone database to manage time zones.
Also, to handle time zones, you will need to store more than just time-of-day. You will need to store the entire date, as a time zone's UTC offset often varies with date. I.e. 09:05 Australia/Sydney doesn't really nail down a moment in time. But 2017-08-16 09:05 Australia/Sydney does.
Here is how you could create such a time stamp with <chrono> and the time zone library:
using namespace date;
using namespace std::chrono;
auto zt = make_zoned("Australia/Sydney", local_days{2017_y/aug/16} + 9h + 5min);
You can print it out like this:
std::cout << zt << '\n';
And the output is:
2017-08-16 09:05:00 AEST
If you want to find out the local time in US/Central that corresponds to this same moment in time:
auto zt2 = make_zoned("US/Central", zt);
std::cout << zt2 << '\n';
And the output is:
2017-08-15 18:05:00 CDT
date::zoned_time<std::chrono::seconds> is the type of zt and zt2 in these examples, and that is what I recommend you store. Under the hood this type is a pairing of {date::time_zone const*, std::chrono::time_point<system_clock, seconds>} (two words of storage).
Source code: https://github.com/HowardHinnant/date
Documentation: http://howardhinnant.github.io/date/tz.html
Video: https://www.youtube.com/watch?v=Vwd3pduVGKY
Why does the following range function...
d3.time.minute.range(
new Date('Sat Aug 17 2013 00:00:00 GMT-0400'),
new Date('Sat Aug 17 2013 06:00:00 GMT-0400'),
22);
...return an array like this...
[
Sat Aug 17 2013 00:00:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 00:22:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 00:44:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 01:00:00 GMT-0400 (Eastern Daylight Time), // << normalized to 1am
Sat Aug 17 2013 01:22:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 01:44:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 02:00:00 GMT-0400 (Eastern Daylight Time), // << normalized to 2am
...
]
...instead of like this?
[
Sat Aug 17 2013 00:00:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 00:22:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 00:44:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 01:06:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 01:28:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 01:50:00 GMT-0400 (Eastern Daylight Time),
Sat Aug 17 2013 02:12:00 GMT-0400 (Eastern Daylight Time),
...
]
I'm trying to render a timeline and then use d3.time.scale to correlate pixels and time. Each rect I render is meant to represent 22 minutes in this example. When I bind .data() to the result of this range function, my text elements don't clearly represent actual time in all cases.
What sort of problems am I going to run into if I avoid using d3.time.minute.range and simply add 22 minutes (.getTime() + 22 * 60 * 1000) myself?
According to what mbostock said here, I think you need to roll your own:
http://grokbase.com/t/gg/d3-js/1344en8cz8/time-scale-always-forcibly-display-first-date-of-a-month
So:
d3.time.minute.range(
new Date('Sat Aug 17 2013 00:00:00 GMT-0400'),
new Date('Sat Aug 17 2013 06:00:00 GMT-0400'))
.filter(function(d) {
return (d - new Date('Sat Aug 17 2013 00:00:00 GMT-0400')) % (22 * 60 * 1000) == 0;
});
Fiddle here:
http://jsfiddle.net/JHTQf/
As far as problems, I think either will be fine since browsers don't have leap seconds. I'd take into account DST but I think that is fixed with UTC calculations.
I have a mktime issue, if the hour does not exist because of DST change, then mktime on windows using MSVS 2010 will return a time_t in the past, in my case for 23:00, when it should return 1:00AM next day (on Linux it is returning 1:00AM as it should). My issue is happening on Brazil timezone (GMT -3) exactly when the auto adjust daylight saving time should happen. In their case this is happening on 21.Oct.2012 at 0:00 AM (this will become 1:00 AM).
This is a part of the code:
/* test_date1.cpp : Defines the entry point for the console application.
*
*/
#include "StdAfx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
int _tmain(int argc, _TCHAR* argv[])
{
time_t mytime=1350784881;
struct tm *timeinfo;
char *tz;
/*time ( &mytime ); */
timeinfo = localtime ( &mytime );
printf("%.2d/%.2d/%.4d, %.2d:%.2d isdst?=%d\n",
timeinfo->tm_mday, timeinfo->tm_mon, timeinfo->tm_year, timeinfo->tm_hour, timeinfo-> tm_min, timeinfo -> tm_isdst);
timeinfo->tm_mday=21;
timeinfo->tm_mon=9;
timeinfo->tm_year=112;
timeinfo->tm_hour=0;
timeinfo->tm_min=0;
timeinfo->tm_isdst=-1;
printf("The shit: %.2d/%.2d/%.4d, %.2d:%.2d isdst?=%d\n",
timeinfo->tm_mday, timeinfo->tm_mon, timeinfo->tm_year, timeinfo->tm_hour, timeinfo-> tm_min, timeinfo -> tm_isdst);
mytime= mktime(timeinfo);
printf("mytime is=%d\n", mytime);
timeinfo = localtime ( &mytime );
printf("%.2d/%.2d/%.4d, %.2d:%.2d isdst?=%d\n",
timeinfo->tm_mday, timeinfo->tm_mon, timeinfo->tm_year, timeinfo->tm_hour, timeinfo-> tm_min, timeinfo -> tm_isdst);
return 0;
}
The results on Windows are:
20/09/0112, 23:01 isdst?=0
21/09/0112, 00:00 isdst?=-1
mytime is=1350784800
20/09/0112, 23:00 isdst?=0
And on Linux are:
20/09/0112, 23:01 isdst?=0
21/09/0112, 00:00 isdst?=-1
mytime is=1350788400
21/09/0112, 01:00 isdst?=1
As you can see mytime diff is 3600 seconds between what time_t returns the C from Unix and what returns the C from Microsoft Visual Studio 2010.
This program should run on different platforms (UNIX/WINDOWS/etc) and on any timezone, so I should not hardcode the timezone.
As you saw the problem is on Windows where the time is returned wrongly. In this moment I don't know how to fix this issue. Did someone had this particular problem? How did you solved it? I specifically need the beginging of the Local Day.
Thanks a lot,
Jokerush
I don't know if the behaviour of mktime is defined when you pass it an invalid time, so this might not actually be a bug.
At any rate, short of re-implementing mktime yourself, you'll need to work around the problem. I propose the following algorithm:
Build a struct tm for 9am on the day in question.
Convert to time_t.
Subtract 24 hours from the time_t.
If there's no daylight savings change, then at this point you're looking at 9am the previous day. If daylight savings started, you're looking at 8am; if it finished, you're looking at 10am.
Convert back to a struct tm.
Compare the date in the struct tm to the original date.
If it isn't the right day yet, add an hour to the time_t and try again.
Since you're only adding an hour at a time, once you've got the date you wanted, you can be sure you've got the earliest time on that date.
I'm making a few assumptions that I think are currently safe: that daylight savings time never starts or finishes part way through an hour, that it never starts or finishes between 8am and 10am, and that it never changes by more than an hour.
I'm intentionally not assuming that daylight savings never starts or finishes in the evening (e.g., 11pm becomes midnight or vice-versa) or in the early morning (e.g., 2am becomes 3am or vice-versa, which as it happens is exactly what happens here).