W3cubDocs

/Crystal

struct Time

Overview

Time represents a date-time instant in incremental time observed in a specific time zone.

The calendaric calculations are based on the rules of the proleptic Gregorian calendar as specified in ISO 8601. Leap seconds are ignored.

Internally, the time is stored as an Int64 representing seconds from epoch (0001-01-01 00:00:00.0 UTC) and an Int32 representing nanosecond-of-second with value range 0..999_999_999.

The supported date range is 0001-01-01 00:00:00.0 to 9999-12-31 23:59:59.999_999_999 in any local time zone.

Telling the Time

There are several methods to retrieve a Time instance representing the current time:

Time.utc                                        # returns the current time in UTC
Time.local Time::Location.load("Europe/Berlin") # returns the current time in time zone Europe/Berlin
Time.local                                      # returns the current time in current time zone

It is generally recommended to keep instances in UTC and only apply a local time zone when formatting for user display, unless the domain logic requires having a specific time zone (for example for calendaric operations).

Creating a Specific Instant

Time instances representing a specific instant can be created by .utc or .new with the date-time specified as individual arguments:

time = Time.utc(2016, 2, 15, 10, 20, 30)
time.to_s # => 2016-02-15 10:20:30 UTC
time = Time.local(2016, 2, 15, 10, 20, 30, location: Time::Location.load("Europe/Berlin"))
time.to_s # => 2016-02-15 10:20:30 +01:00 Europe/Berlin
# The time-of-day can be omitted and defaults to midnight (start of day):
time = Time.utc(2016, 2, 15)
time.to_s # => 2016-02-15 00:00:00 UTC

Retrieving Time Information

Each Time instance allows querying calendar data:

time = Time.utc(2016, 2, 15, 10, 20, 30)
time.year        # => 2016
time.month       # => 2
time.day         # => 15
time.hour        # => 10
time.minute      # => 20
time.second      # => 30
time.millisecond # => 0
time.nanosecond  # => 0
time.day_of_week # => Time::DayOfWeek::Monday
time.day_of_year # => 46
time.monday?     # => true
time.time_of_day # => 10:20:30

For querying if a time is at a specific day of week, Time offers named predicate methods, delegating to #day_of_week:

time.monday? # => true
# ...
time.sunday? # => false

Time Zones

Each time is attached to a specific time zone, represented by a Location (see #location). #zone returns the time zone observed in this location at the current time (i.e. the instant represented by this Time). #offset returns the offset of the current zone in seconds.

time = Time.local(2018, 3, 8, 22, 5, 13, location: Time::Location.load("Europe/Berlin"))
time          # => 2018-03-08 22:05:13 +01:00 Europe/Berlin
time.location # => #<Time::Location Europe/Berlin>
time.zone     # => #<Time::Location::Zone CET +01:00 (3600s) STD>
time.offset   # => 3600

Using .utc, the location is Time::Location::UTC:

time = Time.utc(2018, 3, 8, 22, 5, 13)
time          # => 2018-03-08 22:05:13.0 UTC
time.location # => #<Time::Location UTC>
time.zone     # => #<Time::Location::Zone UTC +00:00 (0s) STD>
time.offset   # => 0

A Time instance can be transformed to a different time zone while retaining the same instant using #in:

time_de = Time.local(2018, 3, 8, 22, 5, 13, location: Time::Location.load("Europe/Berlin"))
time_ar = time_de.in Time::Location.load("America/Buenos_Aires")
time_de # => 2018-03-08 22:05:13 +01:00 Europe/Berlin
time_ar # => 2018-03-08 18:05:13 -03:00 America/Buenos_Aires

Both Time instances show a different local date-time, but they represent the same date-time in the instant time-line, therefore they are considered equal:

time_de.to_utc     # => 2018-03-08 21:05:13 UTC
time_ar.to_utc     # => 2018-03-08 21:05:13 UTC
time_de == time_ar # => true

There are also two special methods for converting to UTC and local time zone:

time.to_utc   # equals time.in(Location::UTC)
time.to_local # equals time.in(Location.local)

#to_local_in allows changing the time zone while keeping the same local date-time (wall clock) which results in a different instant on the time line.

Formatting and Parsing Time

To make date-time instances exchangeable between different computer systems or readable to humans, they are usually converted to and from a string representation.

The method #to_s formats the date-time according to a specified pattern.

time = Time.utc(2015, 10, 12, 10, 30, 0)
time.to_s("%Y-%m-%d %H:%M:%S %:z") # => "2015-10-12 10:30:00 +00:00"

Similarly, Time.parse and Time.parse! are used to construct a Time instance from date-time information in a string, according to a specified pattern:

Time.parse("2015-10-12 10:30:00 +00:00", "%Y-%m-%d %H:%M:%S %z", Time::Location::UTC)
Time.parse!("2015-10-12 10:30:00 +00:00", "%Y-%m-%d %H:%M:%S %z")

See Time::Format for all directives.

Calculations

Time.utc(2015, 10, 10) - 5.days # => 2015-10-05 00:00:00 +00:00

span = Time.utc(2015, 10, 10) - Time.utc(2015, 9, 10)
span.days          # => 30
span.total_hours   # => 720
span.total_minutes # => 43200

Measuring Time

The typical time representation provided by the operating system is based on a "wall clock" which is subject to changes for clock synchronization. This can result in discontinuous jumps in the time-line making it not suitable for accurately measuring elapsed time.

Instances of Time are focused on telling time – using a "wall clock". When Time.local is called multiple times, the difference between the returned instances is not guaranteed to equal to the time elapsed between making the calls; even the order of the returned Time instances might not reflect invocation order.

t1 = Time.utc
# operation that takes 1 minute
t2 = Time.utc
t2 - t1 # => ?

The resulting Time::Span could be anything, even negative, if the computer's wall clock has changed between both calls.

As an alternative, the operating system also provides a monotonic clock. Its time-line has no specfied starting point but is strictly linearly increasing.

This monotonic clock should always be used for measuring elapsed time.

A reading from this clock can be taken using .monotonic:

t1 = Time.monotonic
# operation that takes 1 minute
t2 = Time.monotonic
t2 - t1 # => 1.minute (approximately)

The execution time of a block can be measured using .measure:

elapsed_time = Time.measure do
  # operation that takes 20 milliseconds
end
elapsed_time # => 20.milliseconds (approximately)

Included Modules

Defined in:

json/to_json.cr
time.cr
yaml/to_yaml.cr

Constant Summary

UNIX_EPOCH = new(unsafe_utc_seconds: 62135596800_i64)

This constant is defined to be "1970-01-01 00:00:00 UTC". Can be used to create a Time::Span that represents an Unix Epoch time duration.

Time.utc - Time::UNIX_EPOCH

Constructors

Class Method Summary

Instance Method Summary

Instance methods inherited from module Comparable(Time)

<, <=(other : T) <=, <=>(other : T) <=>, ==(other : T) ==, >(other : T) >, >=(other : T) >=, clamp(min, max)
clamp(range : Range) clamp

Instance methods inherited from struct Struct

==(other) : Bool ==, hash(hasher) hash, inspect(io : IO) : Nil inspect, pretty_print(pp) : Nil pretty_print, to_s(io : IO) : Nil to_s

Instance methods inherited from struct Value

==(other : JSON::Any)
==(other : YAML::Any)
==(other) ==
, dup dup

Instance methods inherited from class Object

! : Bool !, !=(other) !=, !~(other) !~, ==(other) ==, ===(other : JSON::Any)
===(other : YAML::Any)
===(other) ===
, =~(other) =~, as(type : Class) as, as?(type : Class) as?, class class, dup dup, hash(hasher)
hash hash
, in?(*values : Object) : Bool
in?(collection) : Bool in?
, inspect : String
inspect(io : IO) : Nil inspect
, is_a?(type : Class) : Bool is_a?, itself itself, nil? : Bool nil?, not_nil! not_nil!, pretty_inspect(width = 79, newline = "\n", indent = 0) : String pretty_inspect, pretty_print(pp : PrettyPrint) : Nil pretty_print, responds_to?(name : Symbol) : Bool responds_to?, tap(&) tap, to_json(io : IO)
to_json to_json
, to_pretty_json(io : IO, indent : String = " ")
to_pretty_json(indent : String = " ") to_pretty_json
, to_s : String
to_s(io : IO) : Nil to_s
, to_yaml(io : IO)
to_yaml to_yaml
, try(&) try, unsafe_as(type : T.class) forall T unsafe_as

Class methods inherited from class Object

from_json(string_or_io, root : String)
from_json(string_or_io) from_json
, from_yaml(string_or_io : String | IO) from_yaml

Constructor Detail

def self.local(year : Int32, month : Int32, day : Int32, hour : Int32 = 0, minute : Int32 = 0, second : Int32 = 0, *, nanosecond : Int32 = 0, location : Location = Location.local) : TimeSource

Creates a new Time instance representing the given local date-time in location (defaults to local time zone).

time = Time.local(2016, 2, 15, 10, 20, 30, location: Time::Location.load("Europe/Berlin"))
time.inspect # => "2016-02-15 10:20:30.0 +01:00 Europe/Berlin"

Valid value ranges for the individual fields:

The time-of-day can be omitted and defaults to midnight (start of day):

time = Time.utc(2016, 2, 15)
time.to_s # => "2016-02-15 00:00:00 UTC"

The local date-time representation is resolved to a single instant based on the offset observed in the location at this time.

This process can sometimes be ambiguous, mostly due skipping or repeating times at time zone transitions. For example, in America/New_York the date-time 2011-03-13 02:15:00 never occurred, there is a gap between time zones. In return, 2011-11-06 01:15:00 occurred twice because of overlapping time zones.

In such cases, the choice of time zone, and therefore the time, is not well-defined. This method returns a time that is correct in one of the two zones involved in the transition, but it does not guarantee which.

def self.local(location : Location = Location.local) : TimeSource

Creates a new Time instance representing the current time from the system clock observed in location (defaults to local time zone).

def self.new(ctx : YAML::ParseContext, node : YAML::Nodes::Node)Source

def self.new(pull : JSON::PullParser)Source

Reads a string from JSON parser as a time formated according to RFC 3339 or other variations of ISO 8601.

The JSON format itself does not specify a time data type, this method just assumes that a string holding a ISO 8601 time format can be interpreted as a time value.

See #to_json for reference.

def self.new(*, seconds : Int64, nanoseconds : Int32, location : Location)Source

Creates a new Time instance that corresponds to the number of seconds and nanoseconds elapsed from epoch (0001-01-01 00:00:00.0 UTC) observed in location.

Valid range for seconds is 0..315_537_897_599. For nanoseconds it is 0..999_999_999.

def self.parse(time : String, pattern : String, location : Location) : TimeSource

Parses a Time from time string using the given pattern.

See Time::Format for details.

Time.parse("2016-04-05", "%F", Time::Location.load("Europe/Berlin")) # => 2016-04-05 00:00:00.0 +02:00 Europe/Berlin

If there is no time zone information in the formatted time, location will be assumed. When location is nil, in such a case the parser will raise Time::Format::Error.

def self.parse!(time : String, pattern : String) : TimeSource

Parses a Time from time string using the given pattern.

See Time::Format for details.

Time.parse!("2016-04-05 +00:00", "%F %:z") # => 2016-04-05 00:00:00.0 +00:00
Time.parse!("2016-04-05", "%F")            # raises Time::Format::Error

If there is no time zone information in the formatted time, the parser will raise Time::Format::Error.

def self.parse_local(time : String, pattern : String) : TimeSource

Parses a Time from time string using the given pattern and Time::Location.local as default location

See Time::Format for details.

Time.parse_utc("2016-04-05", "%F") # => 2016-04-05 00:00:00.0 +00:00

Time::Location.local will only be used as #location if the formatted time does not contain any time zone information. The return value can't be assumed to be a UTC time (this can be achieved by calling #to_local).

def self.parse_utc(time : String, pattern : String) : TimeSource

Parses a Time from time string using the given pattern and Time::Location::UTC as default location.

See Time::Format for details.

Time.parse_utc("2016-04-05", "%F") # => 2016-04-05 00:00:00.0 +00:00

Time::Location::UTC will only be used as #location if the formatted time does not contain any time zone information. The return value can't be assumed to be a UTC time (this can be achieved by calling #to_utc).

def self.unix(seconds : Int) : TimeSource

Creates a new Time instance that corresponds to the number of seconds elapsed since the Unix epoch (1970-01-01 00:00:00 UTC).

The time zone is always UTC.

Time.unix(981173106) # => 2001-02-03 04:05:06 UTC

def self.unix_ms(milliseconds : Int) : TimeSource

Creates a new Time instance that corresponds to the number of milliseconds elapsed since the Unix epoch (1970-01-01 00:00:00 UTC).

The time zone is always UTC.

time = Time.unix_ms(981173106789) # => 2001-02-03 04:05:06.789 UTC
time.millisecond                  # => 789

def self.utc(*, seconds : Int64, nanoseconds : Int32) : TimeSource

Creates a new Time instance that corresponds to the number of seconds and nanoseconds elapsed from epoch (0001-01-01 00:00:00.0 UTC) in UTC.

Valid range for seconds is 0..315_537_897_599. For nanoseconds it is 0..999_999_999.

def self.utc : TimeSource

Creates a new Time instance representing the current time from the system clock in UTC.

def self.utc(year : Int32, month : Int32, day : Int32, hour : Int32 = 0, minute : Int32 = 0, second : Int32 = 0, *, nanosecond : Int32 = 0) : TimeSource

Creates a new Time instance representing the given date-time in UTC.

time = Time.utc(2016, 2, 15, 10, 20, 30)
time.to_s # => "2016-02-15 10:20:30 UTC"

Valid value ranges for the individual fields:

The time-of-day can be omitted and defaults to midnight (start of day):

time = Time.utc(2016, 2, 15)
time.to_s # => "2016-02-15 00:00:00 UTC"

Since UTC does not have any time zone transitions, each date-time is unambiguously resolved.

def self.week_date(year : Int32, week : Int32, day_of_week : Int32 | DayOfWeek, hour : Int32 = 0, minute : Int32 = 0, second : Int32 = 0, *, nanosecond : Int32 = 0, location : Location = Location.local) : selfSource

Creates an instance specified by a commercial week date consisting of ISO calendar year, week and a day_of_week.

This equates to the results from #calendar_week and #day_of_week.

Valid value ranges for the individual fields:

Class Method Detail

def self.days_in_month(year : Int, month : Int) : Int32Source

Returns the number of days in month (value range: 1..12) taking account of the year.

The returned value is either 28, 29, 30 or 31 depending on the month and whether year is leap.

Time.days_in_month(2016, 2) # => 29
Time.days_in_month(1990, 4) # => 30

def self.days_in_year(year : Int) : Int32Source

Returns the number of days in year.

A normal year has 365 days, a leap year 366 days.

Time.days_in_year(1990) # => 365
Time.days_in_year(2004) # => 366

def self.leap_year?(year : Int) : BoolSource

Returns true if year is a leap year in the proleptic Gregorian calendar.

def self.measure(&) : Time::SpanSource

Measures the execution time of block.

The measurement relies on the monotonic clock and is not affected by fluctuations of the system clock (see #monotonic).

elapsed_time = Time.measure do
  # operation that takes 20 milliseconds
end
elapsed_time # => 20.milliseconds (approximately)

def self.monotonic : Time::SpanSource

Returns a reading from the monotonic clock to measure elapsed time.

Values from the monotonic clock and wall clock are not comparable. This method does not return a Time instance but a Time::Span amounting to the number of nanoseconds elapsed since the unspecified starting point of the monotonic clock. The returned values are strictly linearly increasing.

This clock should be independent from discontinuous jumps in the system time, such as leap seconds, time zone adjustments or manual changes to the computer's clock.

Subtracting two results from this method equals to the time elapsed between both readings:

start = Time.monotonic
# operation that takes 20 milliseconds
elapsed = Time.monotonic - start # => 20.milliseconds (approximately)
# operation that takes 50 milliseconds
elapsed_total = Time.monotonic - start # => 70.milliseconds (approximately)

The execution time of a block can be measured using .measure.

def self.parse_iso8601(time : String)Source

Parse datetime format specified by ISO 8601.

This is similar to .parse_rfc3339 but RFC 3339 defines a more strict format. In ISO 8601 for examples, field delimiters (#-, :) are optional.

Use #to_rfc3339 to format a Time according to .

def self.parse_rfc2822(time : String)Source

Parse time format specified by RFC 2822.

This is also compatible to RFC 882 and RFC 1123.

def self.parse_rfc3339(time : String)Source

Parse time format specified by RFC 3339 (ISO 8601 profile).

Instance Method Detail

def +(span : Time::Span) : TimeSource

Returns a copy of this Time with span added.

See #shift for details.

def +(span : Time::MonthSpan) : TimeSource

Returns a copy of this Time with span added.

It adds the number of months with overflow increasing the year. If the resulting day-of-month would be invalid, it is adjusted to the last valid day of the moneth.

For example, adding 1.month to 2007-03-31 would result in the invalid date 2007-04-31 which will be adjusted to 2007-04-30.

This operates on the local time-line, such that the local date-time represenations of month and year are increased by the specified amount.

If the resulting date-time is ambiguous due to time zone transitions, a correct time will be returned, but it does not guarantee which.

def -(span : Time::MonthSpan) : TimeSource

Returns a copy of this Time with span subtracted.

It adds the number of months with overflow decreasing the year. If the resulting day-of-month would be invalid, it is adjusted to the last valid day of the moneth.

For example, subtracting 1.month from 2007-05-31 would result in the invalid date 2007-04-31 which will be adjusted to 2007-04-30.

This operates on the local time-line, such that the local date-time represenations of month and year are decreased by the specified amount.

If the resulting date-time is ambiguous due to time zone transitions, a correct time will be returned, but it does not guarantee which.

def -(other : Time) : Time::SpanSource

Returns a Time::Span amounting to the duration between other and self.

The time span is negative if self is before other.

The duration amounts to the actual time elapsed between both instances, on the instant time-line. The difference between local date-time representations may equal to a different duration, depending on time zone transitions.

def -(span : Time::Span) : TimeSource

Returns a copy of this Time with span subtracted.

See #shift for details.

def <=>(other : Time) : Int32Source

Compares this Time with other.

The comparison is based on the instant time-line, even if the local date-time representation (wall clock) would compare differently.

To ensure the comparison is also true for local wall clock, both date-times need to be transformed to the same time zone.

def ==(other : Time) : BoolSource

Compares this Time with other for equality.

Two instances are considered equal if they represent the same date-time in the instant time-line, even if they show a different local date-time.

time_de = Time.local(2018, 3, 8, 22, 5, 13, location: Time::Location.load("Europe/Berlin"))
time_ar = Time.local(2018, 3, 8, 18, 5, 13, location: Time::Location.load("America/Buenos_Aires"))
time_de == time_ar # => true

# both times represent the same instant:
time_de.to_utc # => 2018-03-08 21:05:13 UTC
time_ar.to_utc # => 2018-03-08 21:05:13 UTC

def at_beginning_of_day : TimeSource

Returns a copy of this Time representing the beginning of the day.

def at_beginning_of_hour : TimeSource

Returns a copy of this Time representing the beginning of the hour.

def at_beginning_of_minute : TimeSource

Returns a copy of this Time representing the beginning of the minute.

def at_beginning_of_month : TimeSource

Returns a copy of this Time representing the beginning of the month.

def at_beginning_of_quarter : TimeSource

Returns a copy of this Time representing the beginning of the quarter.

def at_beginning_of_second : TimeSource

Returns a copy of this Time representing the beginning of the seconds.

This essentially scaps off nanoseconds.

def at_beginning_of_semester : TimeSource

Returns a copy of this Time representing the beginning of the semester.

def at_beginning_of_week : TimeSource

Returns a copy of this Time representing the beginning of the week.

TODO Ensure correctness in local time-line.

def at_beginning_of_year : TimeSource

Returns a copy of this Time representing the beginning of the year.

def at_end_of_day : TimeSource

Returns a copy of this Time representing the end of the day.

def at_end_of_hour : TimeSource

Returns a copy of this Time representing the end of the hour.

def at_end_of_minuteSource

Returns a copy of this Time representing the end of the minute.

def at_end_of_month : TimeSource

Returns a copy of this Time representing the end of the month.

def at_end_of_quarter : TimeSource

Returns a copy of this Time representing the end of the quarter.

def at_end_of_secondSource

Returns a copy of this Time representing the end of the second.

def at_end_of_semester : TimeSource

Returns a copy of this Time representing the end of the semester.

def at_end_of_week : TimeSource

Returns a copy of this Time representing the end of the week.

TODO Ensure correctness in local time-line.

def at_end_of_year : TimeSource

Returns a copy of this Time representing the end of the year.

def at_midday : TimeSource

Returns a copy of this Time representing midday (12:00) of the same day.

def calendar_week : Tuple(Int32, Int32)Source

Returns the ISO calendar year and week in which this instance occurs.

The ISO calendar year to which the week belongs is not always in the same as the year of the regular calendar date. The first three days of January sometimes belong to week 52 (or 53) of the previous year; equally the last three days of December sometimes are already in week 1 of the following year.

For that reason, this method returns a tuple year, week consisting of the calendar year to which the calendar week belongs and the ordinal number of the week within that year.

Together with #day_of_week this represents a specific day as commercial or week date format year, week, day_of_week in the same way as the typical format year, month, day. .week_date creates a Time instance from a week date.

def clone : TimeSource

def date : Tuple(Int32, Int32, Int32)Source

Returns a Tuple with #year, #month and #day.

def day : Int32Source

Returns the day of the month (1..31).

def day_of_week : Time::DayOfWeekSource

Returns the day of the week (Monday..Sunday).

def day_of_year : Int32Source

Returns the day of the year.

The value range is 1..365 in normal yars and 1..366 in leap years.

def friday? : BoolSource

Returns true if the day of week is Friday.

See #day_of_week for details.

def hash(hasher)Source

Description copied from struct Struct

See Object#hash(hasher)

def hour : Int32Source

Returns the hour of the day (0..23).

def in(location : Location) : TimeSource

Returns a copy of this Time representing the same instant observed in location.

This method changes the time zone and retains the instant, which will usually result in a different representation of local date-time (unless both locations have the same offset).

Ambiguous time zone transitions such as gaps and overlaps have no effect on the result because it retains the same instant.

time_de = Time.local(2018, 3, 8, 22, 5, 13, location: Time::Location.load("Europe/Berlin"))
time_ar = time_de.in Time::Location.load("America/Buenos_Aires")
time_de # => 2018-03-08 22:05:13 +01:00 Europe/Berlin
time_ar # => 2018-03-08 18:05:13 -03:00 America/Buenos_Aires

In contrast, #to_local_in changes to a different location while preserving the same wall time, which results in different instants on the time line.

def inspect(io : IO, with_nanoseconds = true) : NilSource

Prints this Time to io.

The local date-time is formatted as date string YYYY-MM-DD HH:mm:ss.nnnnnnnnn +ZZ:ZZ:ZZ. Nanoseconds are omitted if with_nanoseconds is false. When the location is UTC, the offset is omitted. Offset seconds are omitted if 0.

The name of the location is appended unless it is a fixed zone offset.

def local? : BoolSource

Returns true if #location equals to the local time zone (Time::Location.local).

Since the system's settings may change during a program's runtime, the result may not be identical between different invocations.

def location : LocationSource

Returns Location representing the time-zone observed by this Time.

def millisecond : Int32Source

Returns the millisecond of the second (0..999).

def minute : Int32Source

Returns the minute of the hour (0..59).

def monday? : BoolSource

Returns true if the day of week is Monday.

See #day_of_week for details.

def month : Int32Source

Returns the month of the year (1..12).

def nanosecond : Int32Source

Returns the nanosecond of the second (0..999_999_999).

def offset : Int32Source

Returns the offset from UTC (in seconds) in effect in #location at this instant.

def saturday? : BoolSource

Returns true if the day of week is Saturday.

See #day_of_week for details.

def second : Int32Source

Returns the second of the minute (0..59).

def shift(*, years : Int = 0, months : Int = 0, weeks : Int = 0, days : Int = 0, hours : Int = 0, minutes : Int = 0, seconds : Int = 0, nanoseconds : Int = 0)Source

Returns a copy of this Time shifted by the amount of calendrical units provided as arguments.

Positive values result in a later time, negative values in an earlier time.

This operates on the local time-line, such that the local date-time representation of the result will be apart by the specified amounts, but the elapsed time between both instances might not equal to the combined default durations This is the case for example when adding a day over a daylight-savings time change:

start = Time.new(2017, 10, 28, 13, 37, location: Time::Location.load("Europe/Berlin"))
one_day_later = start.shift days: 1

one_day_later - start # => 25.hours

years is equivalent to 12 months and weeks is equivalent to 7 days.

If the day-of-month resulting from shifting by years and months would be invalid, the date is adjusted to the last valid day of the month. For example, adding one month to 2018-08-31 would result in the invalid date 2018-09-31 which will be adjusted to 2018-09-30:

Time.utc(2018, 7, 31).shift(months: 1) # => Time.utc(2018, 8, 31)
Time.utc(2018, 8, 31).shift(months: 1) # => Time.utc(2018, 9, 30)

Overflow in smaller units is transferred to the next larger unit.

Changes are applied in the same order as the arguments, sorted by increasing granularity. This is relevant because the order of operations can change the result:

Time.utc(2018, 8, 31).shift(months: 1, days: -1)       # => Time.utc(2018, 9, 29)
Time.utc(2018, 8, 31).shift(months: 1).shift(days: -1) # => Time.utc(2018, 9, 29)
Time.utc(2018, 8, 31).shift(days: -1).shift(months: 1) # => Time.utc(2018, 9, 30)

There is no explicit limit on the input values but the shift must result in a valid time between 0001-01-01 00:00:00.0 and 9999-12-31 23:59:59.999_999_999. Otherwise ArgumentError is raised.

If the resulting date-time is ambiguous due to time zone transitions, a correct time will be returned, but it does not guarantee which.

def shift(seconds : Int, nanoseconds : Int) : TimeSource

Returns a copy of this Time shifted by the number of seconds and nanoseconds.

Positive values result in a later time, negative values in an earlier time.

This operates on the instant time-line, such that adding the equivalent of one hour will always be a duration of one hour later. The local date-time representation may change by a different amount, depending on time zone transitions.

Overflow in nanoseconds will be transferred to seconds.

There is no explicit limit on the input values but the addition must result in a valid time between 0001-01-01 00:00:00.0 and 9999-12-31 23:59:59.999_999_999. Otherwise ArgumentError is raised.

def sunday? : BoolSource

Returns true if the day of week is Sunday.

See #day_of_week for details.

def thursday? : BoolSource

Returns true if the day of week is Thursday.

See #day_of_week for details.

def time_of_day : Time::SpanSource

Returns the duration between this Time and midnight of the same day.

This is equivalent to creating a Time::Span from the time-of-day fields:

time.time_of_day == Time::Span.new(hours: time.hour, minutes: time.minute, seconds: time.second, nanoseconds: time.nanosecond)

def to_json(json : JSON::Builder)Source

Emits a string formated according to RFC 3339 (ISO 8601 profile).

The JSON format itself does not specify a time data type, this method just assumes that a string holding a RFC 3339 time format will be interpreted as a time value.

See #from_json for reference.

def to_local : TimeSource

Returns a copy of this Time representing the same instant in the local time zone (Time::Location.local).

See #in for details.

def to_local_in(location : Location)Source

Creates a new Time instance with the same local date-time representation (wall clock) in a different location.

Unlike #in, which always preserves the same instant in time, #to_local_in adjusts the instant such that it results in the same local date-time representation. Both instants are apart from each other by the difference in zone offsets.

new_year = Time.utc(2019, 1, 1, 0, 0, 0)
tokyo = new_year.to_local_in(Time::Location.load("Asia/Tokyo"))
new_york = new_year.to_local_in(Time::Location.load("America/New_York"))
tokyo.inspect    # => "2019-01-01 00:00:00.0 +09:00 Asia/Tokyo"
new_york.inspect # => "2019-01-01 00:00:00.0 -05:00 America/New_York"

def to_rfc2822(io : IO)Source

Format this time using the format specified by RFC 2822 into the given io.

This is also compatible to RFC 882 and RFC 1123.

def to_rfc2822Source

Format this time using the format specified by RFC 2822.

Time.utc(2016, 2, 15).to_rfc2822 # => "Mon, 15 Feb 2016 00:00:00 +0000"

This is also compatible to RFC 882 and RFC 1123.

def to_rfc3339(*, fraction_digits : Int = 0)Source

Format this time using the format specified by RFC 3339 (ISO 8601 profile).

Time.utc(2016, 2, 15).to_rfc3339 # => "2016-02-15T00:00:00Z"

ISO 8601 allows some freedom over the syntax and RFC 3339 exercises that freedom to rigidly define a fixed format intended for use in internet protocols and standards.

Number of seconds decimals can be selected with fraction_digits. Values accepted are 0 (the default, no decimals), 3 (milliseconds), 6 (microseconds) or 9 (nanoseconds).

def to_rfc3339(io : IO, *, fraction_digits : Int = 0)Source

Format this time using the format specified by RFC 3339 (ISO 8601 profile). into the given io.

Number of seconds decimals can be selected with fraction_digits. Values accepted are 0 (the default, no decimals), 3 (milliseconds), 6 (microseconds) or 9 (nanoseconds).

def to_s(format : String) : StringSource

Formats this Time according to the pattern in format.

See Time::Format for details.

time = Time.local(2016, 4, 5)
time.to_s("%F") # => "2016-04-05"

def to_s(io : IO) : NilSource

Prints this Time to io.

The local date-time is formatted as date string YYYY-MM-DD HH:mm:ss +ZZ:ZZ:ZZ. Nanoseconds are always omitted. When the location is UTC, the offset is replaced with the string UTC. Offset seconds are omitted if 0.

def to_s(format : String, io : IO) : NilSource

Formats this Time according to the pattern in format to the given io.

See Time::Format for details.

DEPRECATED Use #to_s(io : IO, format : String) instead

def to_s(io : IO, format : String) : NilSource

Formats this Time according to the pattern in format to the given io.

See Time::Format for details.

def to_unix : Int64Source

Returns the number of seconds since the Unix epoch (1970-01-01 00:00:00 UTC).

time = Time.utc(2016, 1, 12, 3, 4, 5)
time.to_unix # => 1452567845

def to_unix_f : Float64Source

Returns the number of seconds since the Unix epoch (1970-01-01 00:00:00 UTC) as Float64 with nanosecond precision.

time = Time.utc(2016, 1, 12, 3, 4, 5, nanosecond: 678_000_000)
time.to_unix_f # => 1452567845.678

def to_unix_ms : Int64Source

Returns the number of milliseconds since the Unix epoch (1970-01-01 00:00:00 UTC).

time = Time.utc(2016, 1, 12, 3, 4, 5, nanosecond: 678_000_000)
time.to_unix_ms # => 1452567845678

def to_utc : TimeSource

Returns a copy of this Time representing the same instant in UTC (Time::Location::UTC).

See #in for details.

def to_yaml(yaml : YAML::Nodes::Builder)Source

def tuesday? : BoolSource

Returns true if the day of week is Tuesday.

See #day_of_week for details.

def utc? : BoolSource

Returns true if #location equals to Location::UTC.

def wednesday? : BoolSource

Returns true if the day of week is Wednesday.

See #day_of_week for details.

def year : Int32Source

Returns the year of the proleptic Georgian Calendar (0..9999).

def zone : Time::Location::ZoneSource

Returns the time zone in effect in #location at this instant.

© 2012–2020 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/0.35.1/Time.html