b8db6b2001-01-10Mirar (Pontus Hagland) -------------------------------------------------------------------------
6a43f42001-01-10Mirar (Pontus Hagland)  Q: I need to parse some date in a non-strict format, like the one in the HTTP or mail protocol, or from a user web form. A: Calendar.dwim_day, or Calendar.dwim_time, should solve your problem. > Calendar.dwim_day("1/2/3"); Result: Day(Thu 2 Jan 2003) > Calendar.dwim_day("1 aug 2001"); Result: Day(Wed 1 Aug 2001) > Calendar.dwim_time("1 aug 2001 23:14 EDT"); Result: Minute(Wed 1 Aug 2001 23:14 EDT) > Calendar.dwim_time("2001 2 3 23:14:23 UTC+9"); Result: Second(Sat 3 Feb 2001 23:14:23 UTC+9) If it doesn't, and it should, report the problem to me and I'll see what I can do. Note that the timezones are rather unpredictable - if it doesn't get it, you will get the default (local) timezone. -------------------------------------------------------------------------
e1fb492001-01-10Mirar (Pontus Hagland) Q: The dwim_* functions are too slow. A: They are not written to be fast, but to do good guessing. If you know the format, you should use the Calendar.parse function: > Calendar.parse("%Y-%M-%D %h:%m","2040-11-08 2:46"); Result: Minute(Thu 8 Nov 2040 2:46 CET) > Calendar.parse("%Y w%W %e %h:%m %p %z","1913 w4 monday 2:14 pm CET"); Result: Minute(Mon 20 Jan 1913 14:14 CET) These are the format characters: %Y absolute year %y dwim year (70-99 is 1970-1999, 0-69 is 2000-2069) %M month (number, name or short name) (needs %y) %W week (needs %y) %D date (needs %y, %m) %d short date (20000304, 000304) %a day (needs %y) %e weekday (needs %y, %w) %h hour (needs %d, %D or %W) %m minute (needs %h) %s second (needs %m) %f fraction of a second (needs %s) %t short time (205314, 2053) %z zone %p "am" or "pm" %n empty string (to be put at the end of formats) and you can also use "%*[....]" to skip some characters, as in sscanf(). If this is too slow, there is currently no solution in Pike to do this faster, except possibly sscanf and manual calculations/ time object creation. -------------------------------------------------------------------------
b8db6b2001-01-10Mirar (Pontus Hagland) Q: How do I get from unix time (time(2)) to a unit and back? A: Calendar.Unit("unix",time()) unit->unix_time() > Calendar.Day("unix",987654321); Result: Day(Thu 19 Apr 2001) > Calendar.Second("unix",987654321); Result: Second(Thu 19 Apr 2001 6:25:21 CEST) > Calendar.Day()->unix_time(); Result: 979081200 Note that you will get the time for the start of the unit. Unix time is timezone independant. The day-of-time units (seconds, hours, etc) uses this as internal representation of time. ------------------------------------------------------------------------- Q: I'm a mad astronomer, how do I do the same conversions with julian day numbers? A: Julian day numbers are used as the internal representation
d7db392016-07-14Henrik Grubbström (Grubba)  for the day, and for most other bigger-than-time-of-day calculations.
b8db6b2001-01-10Mirar (Pontus Hagland)  > Calendar.Day("julian",2454545); Result: Day(Wed 19 Mar 2008) > Calendar.Second("julian",2430122.0); Result: Second(Tue 6 May 1941 13:00:00 CET) Julian day numbers from day units and bigger are integers, representing the new julian number on that day. Julian day numbers from time of day units are represented in floats. > Calendar.Day()->julian_day(); Result: 2451920 > Calendar.Second()->julian_day(); Result: 2451919.949595 Watch out for the float precision, though. If you haven't compiled your Pike with --with-double-precision, this gives you awkwardly low precision - 6 hours. -------------------------------------------------------------------------
6a43f42001-01-10Mirar (Pontus Hagland) Q: How do I convert a "Second(Sat 3 Feb 2001 23:14:23 UTC+9)" object to my timezone? A: ->set_timezone(your timezone) > Calendar.dwim_time("2001 2 3 23:14:23 PST") ->set_timezone("Europe/Stockholm"); Result: Second(Sun 4 Feb 2001 8:14:23 CET) > Calendar.dwim_time("2001 2 3 23:14:23 PST") ->set_timezone("locale"); Result: Second(Sun 4 Feb 2001 8:14:23 CET) ------------------------------------------------------------------------- Q: How do I print my time object? A: ->format_xxx(); You can either print it unit-sensitive, > Calendar.dwim_time("2001 2 3 23:14:23 PST")->format_nice(); Result: "3 Feb 2001 23:14:23" > Calendar.Week()->format_nice(); Result: "w2 2001" > Calendar.now()->format_nicez(); Result: "10 Jan 10:51:15.489603 CET" or in a format not depending on the unit, > Calendar.Week()->format_ymd(); Result: "2001-01-08" > Calendar.Day()->format_time(); Result: "2001-01-10 00:00:00"
dab2a32015-11-18Martin Nilsson  These are all the formats:
6a43f42001-01-10Mirar (Pontus Hagland) 
dab2a32015-11-18Martin Nilsson  format_commonlog "10/Jan/2001:10:49:57 +0100"
6a43f42001-01-10Mirar (Pontus Hagland)  format_ext_time "Wednesday, 10 January 2001 10:49:57"
42f1722007-05-06Martin Bähr  format_ext_time_short "Wed, 10 Jan 2001 10:49:57 CET"
6a43f42001-01-10Mirar (Pontus Hagland)  format_ext_ymd "Wednesday, 10 January 2001" format_iso_time "2001-01-10 (Jan) -W02-3 (Wed) 10:49:57 UTC+1" format_iso_ymd "2001-01-10 (Jan) -W02-3 (Wed)"
dab2a32015-11-18Martin Nilsson  format_iso_short "20010110T10:49:57"
7a66892017-09-23Martin Nilsson  format_mdy "10/1/1"
6a43f42001-01-10Mirar (Pontus Hagland)  format_mod "10:49" format_month "2001-01" format_month_short "200101" format_mtime "2001-01-10 10:49"
dab2a32015-11-18Martin Nilsson  format_nice "10 Jan 2001 10:49:57" format_nicez "10 Jan 2001 10:49:57 CET"
6a43f42001-01-10Mirar (Pontus Hagland)  format_time "2001-01-10 10:49:57" format_time_short "20010110 10:49:57" format_time_xshort "010110 10:49:57" format_tod "10:49:57" format_tod_short "104957" format_todz "10:49:57 CET" format_todz_iso "10:49:57 UTC+1" format_week "2001-w2" format_week_short "2001w2" format_iso_week "2001-W02" format_iso_week_short "200102" format_xtime "2001-01-10 10:49:57.539198" format_xtod "10:49:57.539658" format_ymd "2001-01-10" format_ymd_short "20010110" format_ymd_xshort "010110" format_ctime "Wed Jan 10 10:49:57 2001\n" format_smtp "Wed, 10 Jan 2001 10:49:57 +0100" format_http "Wed, 10 Jan 2001 09:49:57 GMT"
dab2a32015-11-18Martin Nilsson  For objects with a size, e.g. when taking the distance between two time points, the format_elapsed function can also be called to get something similar to "35d8:06:41.547".
6a43f42001-01-10Mirar (Pontus Hagland) ------------------------------------------------------------------------- Q: How old am I? A: First, you need to create the time period representing your age. > object t=Calendar.dwim_time("1638 dec 23 7:02 pm") ->distance(Calendar.now()); Result: Fraction(Thu 23 Dec 1638 19:02:00.000000 LMT - Wed 10 Jan 2001 10:53:33.032856 CET) Now, you can ask for instance how many years this is: > t->how_many(Calendar.Year); Result: 362 Or how many 17 seconds it is: > t->how_many(Calendar.Second()*17); Result: 672068344 A note here is to use ->distance, and not ->range, since that will include the destination unit too: > Calendar.dwim_day("00-01-02")->range(Calendar.Week(2000,2)) ->how_many(Calendar.Day()); Result: 15 > Calendar.dwim_day("00-01-02")->distance(Calendar.Week(2000,2)) ->how_many(Calendar.Day()); Result: 8 ------------------------------------------------------------------------- Q: In 983112378 days, what weekday will it be? A: (this weekday + 983112378) % 7 ;) or take this day, add the number, and ask the object: > (Calendar.Day()+983112378)->week_day_name(); Result: "Saturday" "+int" will add this number of the unit to the unit; this means that Calendar.Year()+2 will move two years forward, but Calendar.now()+2 will not move at all - since now has zero size. To add a number of another time unit, simply do that: > Calendar.Day()+3*Calendar.Year(); Result: Day(Sat 10 Jan 2004) > Calendar.Day()+3*Calendar.Minute()*134; Result: Minute(Wed 10 Jan 2001 6:42 CET - Thu 11 Jan 2001 6:42 CET) The last result here is because the resulting time still will be as long as the first. -------------------------------------------------------------------------
b8db6b2001-01-10Mirar (Pontus Hagland) Q: Are there other calendars? A: Yes.
d7db392016-07-14Henrik Grubbström (Grubba)  Calendar.Day is really a shortcut to Calendar.ISO.Day.
b8db6b2001-01-10Mirar (Pontus Hagland)  There is currently: Gregorian This is the base module for Julian style calendars; despite the name. Most calendars of today are in sync with the Gregorian calendar. ISO This inherits the Gregorian calendar to tweak it to conform to the ISO standards. Most affected are weeks, which starts on Monday in the ISO calendar. This is also the default calendar. Discordian The Discordian calendar as described in Principia Discordia is in sync with the Gregorian calendar (although some claim that it should be the Julian - I go with what I can read from my Principia Discordia). The module inherits and tweaks the Gregorian module. Coptic The Coptic calendar is by some sources ("St. Marks' Coptic Orthodox Church" web pages) is for now on in sync with the Gregorian Calendar, so this module too inherits and tweaks the Gregorian module. It needs to be adjusted for historical use. Julian This is the Julian calendar, with the small changes to the Gregorian calendar (leap years).
da53a82006-01-06Martin Bähr  Badi (Baha'i) The Badi calendar used by the Baha'i religion is based on the solar year. For the time being it is in sync with the Gregorian calendar.
b8db6b2001-01-10Mirar (Pontus Hagland)  Islamic This is the Islamic calendar, using the 'Calendrical Calculations' rules for new moon. It is based directly on the YMD module. Stardate This is the (TNG) Stardate calendar, which consists of one time unit only, the Tick (1000 Tick is one earth year). It is based directly on TimeRanges. ------------------------------------------------------------------------- Q: How do I convert between the calendars? A: You give the unit to be converted to the constructor of the unit you want it to be. > Calendar.Coptic.Day(Calendar.dwim_day("14 feb 1983")); Result: Day(Mon 7 Ams 1699) > Calendar.Islamic.Minute(Calendar.dwim_day("14 feb 1983")); Result: Minute(aha 29 Rebîul-âchir 1403 AH 13:00 CET - ith 1 Djumâda'l-ûla 1403 AH 13:00 CET) > Calendar.Day(Calendar.Stardate.Tick(4711)); Result: Day(Sat 17 Sep 2327 0:00 sharp) ------------------------------------------------------------------------- Q: Isn't there a <my country> calendar? A: <your country> uses the ISO calendar, with just different names for the months. Language is a parameter to the calendar units, as well as the timezone. You set the language by using ->set_language(yourlanguage).
fcfef32001-01-12Mirar (Pontus Hagland)  > t->set_language("pt")->format_ext_ymd();
b8db6b2001-01-10Mirar (Pontus Hagland)  Result: "Quarta-feira, 10 Janeiro 2001" > t->set_language("roman")->format_ext_ymd(); Result: "Mercurii dies, X Ianuarius MMDCCLIII ab urbe condita"
fcfef32001-01-12Mirar (Pontus Hagland)  Note that all languages aren't supported. If you miss your favourite language or I got it all wrong (or have some time over to help me out), look in the Language.pmod file and send me an update.
b8db6b2001-01-10Mirar (Pontus Hagland)  Or send me a list of the weekdays and month names (please start with Monday and January). Currently, these languages are supported:
fcfef32001-01-12Mirar (Pontus Hagland)  name code ------------------------------- ISO (default, aka English)
b235102001-01-12Mirar (Pontus Hagland)  Afrikaans af afr (South Africa),
fcfef32001-01-12Mirar (Pontus Hagland)  Austrian de_AT
b235102001-01-12Mirar (Pontus Hagland)  Basque eu eus (Spain) Catalan ca cat (Catalonia) Croatian hr hrv Danish da dan Dutch nl nld English en eng Estonian et est Faroese fo fao Finnish fi fin French fr fra Galician gl glg (Spain) German de deu Greenlandic kl kal Hungarian hu hun Icelandic is isl Irish ga gle (Gaelic) Italian it ita Latvian lv lav Lithuanian lt lit Norwegian no nor Persian fa fas (Iran) Polish pl pol Portugese pt por Romanian ro ron Serbian sr srp (Yugoslavia) Slovenian sl slv Spanish es spa Swedish sv swe Turkish tr Welsh cy cym Latin la lat
fcfef32001-01-12Mirar (Pontus Hagland)  Roman (Roman Latin)
b8db6b2001-01-10Mirar (Pontus Hagland)  ------------------------------------------------------------------------- Q: Isn't there a <whatever> calendar? A: Not if it isn't listed above. I'll appreciate any implementation help if you happen to have the time over to implement some calendar. I know I miss these: Chinese Jewish or Hebreic Maya Of these, the two first are based on astronomical events, which I haven't had the time to look into yet, but the last - Maya - is totally numeric. ------------------------------------------------------------------------- Q: I don't like that weeks starts on Mondays.
34e7f02001-01-10Mirar (Pontus Hagland)  Every school kids knows that weeks start on Sundays.
b8db6b2001-01-10Mirar (Pontus Hagland) 
34e7f02001-01-10Mirar (Pontus Hagland) A: According to the ISO 8601 standard, weeks start on mondays.
b8db6b2001-01-10Mirar (Pontus Hagland) 
d7db392016-07-14Henrik Grubbström (Grubba)  If you don't like it, use Calendar.Gregorian.Day, etc.
b8db6b2001-01-10Mirar (Pontus Hagland)  -------------------------------------------------------------------------
6a43f42001-01-10Mirar (Pontus Hagland) Q: How do I find out which days are red in a specific region? A: Events.<region> - contains the events for the region, as a SuperEvent. You can ask this object to filter out the holidays, Events.se->holidays(); which will be a superevent containing only holidays. To use this information, you can for instance use ->scan, here in an example to see what red days there are in Sweden the current month: > Calendar.Events.se->filter_flag("h")->scan(Calendar.Month()); Result: ({ /* 6 elements */ Day(Sun 7 Jan 2001), Day(Sun 14 Jan 2001), Day(Sun 21 Jan 2001), Day(Sun 28 Jan 2001), Day(Sat 6 Jan 2001), Day(Mon 1 Jan 2001) }) ------------------------------------------------------------------------- Q: How accurate are the events information?
d7db392016-07-14Henrik Grubbström (Grubba) A: For some regions, very. For most regions, not very.
6a43f42001-01-10Mirar (Pontus Hagland)  The first reason is lack of information of this kind on the web, especially sorted into useful rules (like "the third monday after 23 dec", not "8 jan"). The second reason is lack of time and interest to do research, which is a rather tedious job. If you want to help, the check your region in the
115ea02003-09-26Mirar (Pontus Hagland)  events/regions file and send me <mirar+pike@mirar.org> a patch.
6a43f42001-01-10Mirar (Pontus Hagland)  Don't send me "the x region is all wrong!" mails without
d7db392016-07-14Henrik Grubbström (Grubba)  telling me what it should look like.
6a43f42001-01-10Mirar (Pontus Hagland)  -------------------------------------------------------------------------
34e7f02001-01-10Mirar (Pontus Hagland) Q: My timezone says it's DST. It's wrong. A: No it isn't. But: o The local timezone detector failed to find your timezone by itself, or found the wrong timezone. o or you use the wrong timezone. To make sure the right timezone is used, use the standard timezone names. Those aren't "CET" or "PST", but "Europe/Amsterdam" or "America/Dawson". OR this may be in the future and you have a changed DST rule and uses an old Pike. Then you can either download a new version or download new timezone data files from the ftp address below (if the internet still is there). -------------------------------------------------------------------------
6a43f42001-01-10Mirar (Pontus Hagland) Q: The regional events and nameday files are awesome. May I use them for a project separate from Pike?
115ea02003-09-26Mirar (Pontus Hagland) A: Yes. But send me <mirar+pike@mirar.org> updates!
6a43f42001-01-10Mirar (Pontus Hagland)  ------------------------------------------------------------------------- Q: The timezone information files are awesome. May I use them for a project separate from Pike? A: The timezone files are from a special timezone project, ftp://elsie.nci.nih.gov/pub/ and are free to use, so it's not even up to me. They are not altered from the tzdata.tar.gz files. -------------------------------------------------------------------------