Created
February 26, 2012 16:40
-
-
Save gfldex/1917526 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
http://www.haskell.org/ghc/docs/7.4-latest/html/libraries/haskell98-2.0.0.1/Time.html | |
http://en.wikipedia.org/wiki/Gregorian_calendar | |
http://en.wikipedia.org/wiki/Leap_year | |
http://en.wikipedia.org/wiki/Leap_second | |
http://en.wikipedia.org/wiki/Unix_time | |
# we have 3 different official international clocks right now: | |
say now.IAT; # International Atomic Time | |
say now.GPS; # == IAT - 19s; | |
say now.UTC; # moving away from IAT by 1s every 18 month on average over a decade, that may or may not change | |
# lets decide what forum posts to display | |
my $last-visit = $session.last-visit; | |
my @post-to-display := @posts.grep: ($last-visit - .posted-at) < 24h; | |
# h would be a postfix:<h> that converts Int -> Hour | |
# having something like Calendar::postfix:<m> is handy because a calendaric | |
# minute can be 59 | 60 | 61 sec. | |
# The whole leap second thing is a pain in rear, quite fankly. No wonder why | |
# they are discussing to give up on it. Neither International Atomic Time nor | |
# GPS time got a leap second (or satelites would fall out of the sky). So | |
# to convert GPS time (there are embedded systems that fetch time via GPS) | |
# to UTC requires a lookup in a static table. One can't predict if a year needs | |
# a leap second further then 6 month ahead. Don't ask what happens if NTP comes | |
# into play, that depends on implementation. Microsoft seams not to care to care. | |
# Now lets have a look when and how this can cause tears. | |
my $tom = Person.new(birth => Date.new('2012-01-29')); | |
my $birthday_party = $top.birth | |
+ 365 * 24 * 60 * 60 # one year later | |
+ 3 * 24 * 60 * 60; # that would be 3 days later with SI minutes | |
say "Tom's 1th birthday party will be at ", $birthday_party.day-short-name; | |
# This can either result in "Th" or in "Fr" depending on if January of 2013 got a | |
# leap second or not. | |
# One can get around those problems by doing arithmetics with dates by | |
# decomposing Intervals into minutes, hours and seconds and being really carefull | |
# what they are added on. Just adding seconds to some more seconds relative to | |
# some Unix epoch will result in tears because of missed birthday parties. | |
# But back on track how some nice handling of Temporals (that should not be | |
# Temporals but Calendarics) could look like. | |
# we want to go skating! | |
say "Lets go skating!" if today ~~ all( January | Sunday ); | |
# we have a meeting every monday, so we need any monday that is a workday for this year | |
# A Year would have a member @days (lazy list) that takes leap years into account | |
my $current-year = Date.Year(2012); | |
for $current-year.days ~~ Monday -> $day { | |
next if Calendaric::holiday($day, :region('Saxony')); # we have different holidays for different countries in Germany because of historic religious preference (don't ask) | |
say $day.local-time + 9h + 15m, 'is a meeting'; # let's hope the OS is setup properly | |
} | |
# One might want to convert Gregorian Dates into Chinese dates because if you | |
# get the wedding day wrong in China, your willy will fall off in the first | |
# night and then bad things will happen. | |
sub today ( --> Day ) { Day.new(now) } | |
if today ~~ Calendar::Gregorian { | |
say today.traditinal-chinese; | |
} | |
# There are days in the Julian calendar that do not exist in the Gregorian and | |
# vice versa, so the following could fail | |
if $user ~~ Historian { | |
say today, ' would be ' today.julian; | |
} | |
# Since there are years with missing days, being able not to care would be nice. | |
# The best way to do so would be to have a Iterator that knows how to handle those cases. | |
my $day-of-birth = Date.new('1978-03-01'); | |
for $day-of-birth.years -> $d { | |
last if $d.year > $day-of-birth.year + 120y; | |
say "Yay, birthday party is ", $d.weeday-name, ' the ', $d.day-of-month, '!'; | |
} | |
# Another solution would be a mutable postfix:<++> on the year part | |
my $d_it = $day-of-birth.clone; | |
while( $d_it.year++ < (1978+120)y ){ # we will start in 1979 in this case | |
say "Yay, birthday party is ", $d_it.weeday-name, ' the ', $d_it.day-of-month, '!'; | |
} | |
# Having Exceptions is handy by handling Dates because one can create invalid | |
# Dates fairly easy with seamingly sane arithmetics. Thanks to leap seconds and | |
# years we have to make a difference between counting seconds (for profiling) | |
# or if we handle Date and Time. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment