Blame it on Caesar!
A presentation by
Lennart Regebro
Lunar calendars:
The year is twelve lunar months long.
The year is out of sync with the seasons.
Examples: The Islamic calendar
Lunisolar calendars:
The year is twelve or thirteen lunar months long.
The year is kept in sync with the seasons by leap months.
Examples: The Hebrew, Buddhist, Burmese, Babylonian, etc, etc...
Solar calendars:
The year follows the solstices/seasons.
The moon is ignored completely.
Examples: The French republican calendar, the Julian Calendar, the Ancient Egyptian calendar
and it's descendants.
My calendar is better than yours!
def day_of_year(month, day):
return (month - 1) * 30 + day_of_month
def day_of_week(day):
return ((day - 1) % 10) + 1
def weekno(month, day):
return ((day_of_year(month, day) - 1) // 10) + 1
MONTH_LENGHTS_STD = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
MONTH_LENGHTS_LYR = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]
MONTH_DAY_OF_WEEK = [0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4]
def day_of_year(year, month, day):
if not year % 4 and year % 100 or not year % 400:
d = MONTH_LENGHTS_LYR[month-1]
else:
d = MONTH_LENGHTS_STD[month-1]
return d + day
def day_of_week(year, month, day):
if month < 3:
year -= 1
dow = (year + year//4 - year//100 + year//400 +
MONTH_DAY_OF_WEEK[month-1] + day) % 7
if dow == 0:
dow = 7
return dow
def _weekno(year, month, day):
return (day_of_year(year, month, day) -
day_of_week(year, month, day) + 10) // 7
def weekno(year, month, day):
week = _weekno(year, month, day)
if week == 0:
week = _weekno(year - 1, 12, 31)
if week == 53:
if _weekno(year + 1, 1, 1) == 1:
week = 1
return week
momentjs.com
http://www.date4j.net/
BST: 5 different zones
CST: 4 different zones
IST: 4 different zones
America/Chicago
Australia/Canberra
Asia/Shanghai
Asia/Taipei
>>> from datetime import date
>>> date(2011, 2, 29)
Traceback (most recent call last):
File "", line 1, in
ValueError: day is out of range for month
js> new Date(2011, 1, 29);
Tue Mar 01 2011 00:00:00 GMT+0100 (CET)
js> y = 2011; m = 1; d = 29;
js> dt = new Date(y, m, d);
js> if (dt.getFullYear() !== y ||
dt.getMonth() !== m ||
dt.getDay() !== d) {
> (Insert error handling here)
> }
$ TZ='Europe/Rome' js
Rhino 1.7 release 3 2012 02 16
js> new Date(1972, 4, 28);
Sat May 27 1972 23:00:00 GMT+0100 (CET)
js> new Date(y, m, d, 3);
Sun May 28 1972 03:00:00 GMT+0200 (CEST)
Python & Timezones
pytz 15 - 0 dateutil
pytz 15 - 15 dateutil
pytz 30 - 15 dateutil
pytz 30 - 30 dateutil
Which half past three do you mean?
>>> rome = pytz.timezone('Europe/Rome')
>>> rome.localize(datetime(1972, 5, 28, 0, 0), is_dst=None)
Traceback (most recent call last):
File "", line 1, in
File "/usr/lib/python2.7/dist-packages/pytz/tzinfo.py",
line 322, in localize
raise NonExistentTimeError(dt)
pytz.exceptions.NonExistentTimeError: 1972-05-28 00:00:00
>>>
pytz 40 - 30 dateutil
pytz 40 - 40 dateutil
http://pypi.python.org/pypi/tzlocal
Advantage pytz
Parsing timezones
>>> from dateutil.parser import parse
>>> parse('2003-09-25 12:45 -0300')
datetime.datetime(2003, 9, 25, 12, 45,
tzinfo=tzoffset(None, -10800))
>>> parse('2003-09-25 12:45 GMT-0300')
datetime.datetime(2003, 9, 25, 12, 45,
tzinfo=tzoffset(None, 10800))
RFC 5545 aka iCalendar
RFC 2445 is obsolete
+----------+--------+--------+-------+-------+------+-------+------+
| |SECONDLY|MINUTELY|HOURLY |DAILY |WEEKLY|MONTHLY|YEARLY|
+----------+--------+--------+-------+-------+------+-------+------+
|BYMONTH |Limit |Limit |Limit |Limit |Limit |Limit |Expand|
+----------+--------+--------+-------+-------+------+-------+------+
|BYWEEKNO |N/A |N/A |N/A |N/A |N/A |N/A |Expand|
+----------+--------+--------+-------+-------+------+-------+------+
|BYYEARDAY |Limit |Limit |Limit |N/A |N/A |N/A |Expand|
+----------+--------+--------+-------+-------+------+-------+------+
|BYMONTHDAY|Limit |Limit |Limit |Limit |N/A |Expand |Expand|
+----------+--------+--------+-------+-------+------+-------+------+
|BYDAY |Limit |Limit |Limit |Limit |Expand|Note 1 |Note 2|
+----------+--------+--------+-------+-------+------+-------+------+
|BYHOUR |Limit |Limit |Limit |Expand |Expand|Expand |Expand|
+----------+--------+--------+-------+-------+------+-------+------+
|BYMINUTE |Limit |Limit |Expand |Expand |Expand|Expand |Expand|
+----------+--------+--------+-------+-------+------+-------+------+
|BYSECOND |Limit |Expand |Expand |Expand |Expand|Expand |Expand|
+----------+--------+--------+-------+-------+------+-------+------+
|BYSETPOS |Limit |Limit |Limit |Limit |Limit |Limit |Limit |
+----------+--------+--------+-------+-------+------+-------+------+
dateutil.easter
dateutil.rrule
DTSTART;TZID=America/New_York:19980119T020000
DTSTART:19980119T080000Z
DTSTART:19980119T020000
http://pypi.python.org/pypi/icalendar
- Mixing timezoned and timezone-naive events?
- Conferences on boats?
- End-date or duration?
https://github.com/collective/jquery.recurrenceinput.js
http://regebro.wordpress.com/