{"action":"created","issue":{"url":"https://api.github.com/repos/crystal-lang/crystal/issues/2481","repository_url":"https://api.github.com/repos/crystal-lang/crystal","labels_url":"https://api.github.com/repos/crystal-lang/crystal/issues/2481/labels{/name}","comments_url":"https://api.github.com/repos/crystal-lang/crystal/issues/2481/comments","events_url":"https://api.github.com/repos/crystal-lang/crystal/issues/2481/events","html_url":"https://github.com/crystal-lang/crystal/pull/2481","id":149558545,"number":2481,"title":"Time: honor Daylight Saving and ENV[\"TZ\"]","user":{"login":"asterite","id":209371,"avatar_url":"https://avatars.githubusercontent.com/u/209371?v=3","gravatar_id":"","url":"https://api.github.com/users/asterite","html_url":"https://github.com/asterite","followers_url":"https://api.github.com/users/asterite/followers","following_url":"https://api.github.com/users/asterite/following{/other_user}","gists_url":"https://api.github.com/users/asterite/gists{/gist_id}","starred_url":"https://api.github.com/users/asterite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asterite/subscriptions","organizations_url":"https://api.github.com/users/asterite/orgs","repos_url":"https://api.github.com/users/asterite/repos","events_url":"https://api.github.com/users/asterite/events{/privacy}","received_events_url":"https://api.github.com/users/asterite/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-04-19T19:31:41Z","updated_at":"2016-04-19T20:16:35Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/crystal-lang/crystal/pulls/2481","html_url":"https://github.com/crystal-lang/crystal/pull/2481","diff_url":"https://github.com/crystal-lang/crystal/pull/2481.diff","patch_url":"https://github.com/crystal-lang/crystal/pull/2481.patch"},"body":"With this, `Time.now` behaves exactly like in Ruby, and `ENV[\"TZ\"]` is honored.\r\n\r\nRunning this script:\r\n\r\n```crystal\r\ntime_zones = [\r\n  \"\",\r\n  \"America/New_York\",\r\n  \"Africa/Luanda\",\r\n  \"Africa/Tunis\",\r\n  \"EST\",\r\n  \"Europe/Andorra\",\r\n  \"Europe/Berlin\",\r\n  \"PST\",\r\n  \"America/Noronha\",\r\n  \"America/Belem\",\r\n  \"America/Fortaleza\",\r\n  \"America/Recife\",\r\n  \"America/Araguaina\",\r\n  \"America/Maceio\",\r\n  \"America/Bahia\",\r\n  \"America/Sao_Paulo\",\r\n  \"America/Campo_Grande\",\r\n  \"America/Cuiaba\",\r\n  \"America/Santarem\",\r\n  \"America/Porto_Velho\",\r\n  \"America/Boa_Vista\",\r\n  \"America/Manaus\",\r\n  \"America/Eirunepe\",\r\n  \"America/Rio_Branco\",\r\n  \"America/Argentina/Buenos_Aires\",\r\n]\r\ntime_zones.each do |tz|\r\n  ENV[\"TZ\"] = tz\r\n  puts \"~~~\"\r\n  puts tz\r\n  puts Time.now\r\nend\r\n```\r\n\r\nproduces the same output in Ruby and Crystal, so I guess this implementation is right.\r\n\r\nIt turned out that `gettimeofday` doesn't set the timezone and doesn't honor `ENV[\"TZ\"]`, [or so it seems](http://stackoverflow.com/questions/28375324/why-changing-timezone-from-shell-does-not-affect-gettimeofday-even-after-reboo). Checking Ruby's source code I see they use other C functions. One of them is `localtime_r`, and that does set the daylight saving in the `tm` struct. I guess if it's `tm_isdst` is not zero then the change is by one hour, I don't know if in other places DST changes time in a different way.\r\n\r\nIt would be awesome if you can test this change in your timezone.\r\n\r\nI added a spec to check that the timezone does change when changing `ENV[\"TZ\"]`, though testing that dst is picked up correctly is probably harder."},"comment":{"url":"https://api.github.com/repos/crystal-lang/crystal/issues/comments/212108343","html_url":"https://github.com/crystal-lang/crystal/pull/2481#issuecomment-212108343","issue_url":"https://api.github.com/repos/crystal-lang/crystal/issues/2481","id":212108343,"user":{"login":"asterite","id":209371,"avatar_url":"https://avatars.githubusercontent.com/u/209371?v=3","gravatar_id":"","url":"https://api.github.com/users/asterite","html_url":"https://github.com/asterite","followers_url":"https://api.github.com/users/asterite/followers","following_url":"https://api.github.com/users/asterite/following{/other_user}","gists_url":"https://api.github.com/users/asterite/gists{/gist_id}","starred_url":"https://api.github.com/users/asterite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asterite/subscriptions","organizations_url":"https://api.github.com/users/asterite/orgs","repos_url":"https://api.github.com/users/asterite/repos","events_url":"https://api.github.com/users/asterite/events{/privacy}","received_events_url":"https://api.github.com/users/asterite/received_events","type":"User","site_admin":false},"created_at":"2016-04-19T20:16:35Z","updated_at":"2016-04-19T20:16:35Z","body":"@jhass Ruby can do that because each Time carries a timezone. In Crystal (like in C#) a Time only knows if it's local or UTC (or that info is unknown).\r\n\r\nTo be honest, I don't really like that. I think we can make it so that each Time carries around timezone info. In the future we thought about adding another type for this, TimeWithZone, but it will make things harder to work with, I think. For example in Go a [Time carries that info](https://golang.org/src/time/time.go?s=1855:2369#L29), so I don't see why we can't do that too. Time will be a bit bigger, probably not the size of an `UInt64` anymore, but writing code will be easier, and we'll just need one `Time` type for all use cases.\r\n\r\n@waj what do you think?"}}