Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Ruby Time#dst?

Perhaps a daft question that demonstrates my lack of understanding of daylight saving fundamentals, but as per the title, how does Time.dst? know whether the time object is indeed true or false?

Presumably this must be discernible by the combination of the Date and the Timezone, but then that doesn't make sense as lower latitudes in timezones don't use daylight savings? Therefore surely it must need location to discern #dst? ?

What am i missing?

like image 325
jbk Avatar asked Sep 20 '15 22:09

jbk


People also ask

What is time now in Ruby?

The now() is an inbuilt method in Ruby returns the current time. Syntax: time.now() Parameters: The function accepts no parameter. Return Value: It returns the current time.

How do you parse time in Ruby?

Ruby | DateTime parse() function DateTime#parse() : parse() is a DateTime class method which parses the given representation of date and time, and creates a DateTime object. Return: given representation of date and time, and creates a DateTime object.


2 Answers

To deal with time zones and daylight savings time, Ruby, like just about everything else, is calling the localtime_r C function. This puts the time in a C structure called tm which includes a field called isdst. Ruby is reading that flag.

localtime_r calculates isdst first by getting your time zone from the global tzname variable. tzname is determined by calling tzset. How tzset does its job is system dependent. It can come from the TZ environment variable, reading a file, or querying an OS service.

For example.

# Time zone from the system.
$ ruby -e 'puts Time.now.zone; puts Time.now.dst?'
PDT
true

# Time zone from the TZ environment variable.
$ TZ='Australia/Brisbane' ruby -e 'puts Time.now.zone; puts Time.now.dst?'
AEST
false

Once it has the time zone, localtime_r can convert from GMT to the desired time zone (using the rules which applied on that date) using the "tz database" aka "tzdata" aka "zoneinfo" aka "the Olson database" after its creator Arthur David Olson. Previously a private effort, this is now maintained by IANA. It is a set of files installed on your system, or shipped with Ruby, which contains Far More Than Everything You Ever Want To Know About Time Zones and Daylight Savings.

The tz database treats daylight savings (and other weird things like War and Peace time) as just another time zone. Time zone records are kept going all the way back as far as we've had time zones. Before we had time zones solar noon for that location is used. Because of these historical complications and shifting time zones, the tz database prefers to work with cities (such as "America/New York") and determine the time zone for you.

The time zone data files contain extensive commentary and background, if you're interested in the history of calendaring they're a fascinating read.

like image 142
Schwern Avatar answered Sep 20 '22 03:09

Schwern


The Ruby 2.2.0 Time.dst? method refers to the time_isdst(...) function in time.c:

// ...
return tobj->vtm.isdst ? Qtrue : Qfalse

Which seems correspond to the UNIX struct tm tm_isdt member, after plenty of mangling:

int    tm_isdst daylight savings flag

Search for tm_isdst and isdst in time.c to read about how it is computed.

like image 44
maerics Avatar answered Sep 22 '22 03:09

maerics