pax_global_header00006660000000000000000000000064133403303310014503gustar00rootroot0000000000000052 comment=e920f168a87f99183b0aa7290d6c3af222582d43 convertdate-2.1.3/000077500000000000000000000000001334033033100140245ustar00rootroot00000000000000convertdate-2.1.3/.gitignore000066400000000000000000000004501334033033100160130ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr build dist *.egg-info *.egg *.pyc .tox .eggs py35 convertdate-2.1.3/.travis.yml000066400000000000000000000007261334033033100161420ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr language: python python: - 2.7 - 3.3 - 3.4 - 3.5 - 3.6 - pypy - pypy3 matrix: allow_failures: - python: 3.3 - python: pypy3 # Use container-based infrastructure sudo: false script: - python setup.py test convertdate-2.1.3/HISTORY.rst000066400000000000000000000036271334033033100157270ustar00rootroot00000000000000History ------- 2.1.3 ----- * Bump requirements 2.1.2 ----- * Additional Jewish holidays (thanks, @ohadeytan) * Upload source distributions to Pypi (#10) 2.1.1 ----- * Add Coptic (Alexandrian) calendar converter. * Add explicit support for Python 3.6. 2.1.0 ----- * Change Exception thrown on illegal dates to ValueError. * Add Comte's Positivist calendar. * Bump requirement versions. 2.0.8 ----- * Fix Persian weekday order (thanks, @meyt) 2.0.7 ----- * Better Python 2/3 compatibility * Improve tests * bump pytz requirement 2.0.6 ----- * Executing holidays module returns class with current year, not '2014'. * Expand tests for French Republican, Bahai, Persian, holidays * Add Travis CI testing Bug fixes: * Fix edge case when detecting the day of fall equinox in French Republican calendar * Fix minor methods of calculating French Republican leap years. * Change holidays.holidays.fathers_day from a method to a property * Add pulaski_day to holidays.holidays * Add pytz is dependency list 2.0.5 ----- Bug fixes: * Fix Yom Kippur error in holidays.py (issue #3) 2.0.4 ----- Bug fixes: * Typo in name of holidays.independence_day method * Fix major bug in ordinal.from_gregorian Other changes: * Expand and organized tests 2.0.3.1 ------- Features: - Add `ordinal` module, for counting the day of year - Added Mexican national holidays - Add `monthcalendar` functions Other changes: * Simplified logic in `ISO` module 2.0.3 ----- Features: - Add list of day names and `day_name` function to French Republican converter - Add multiple conversion methods to the French Republican calendar - Add Dublin day count and Julian day count converters - Add month names to Bahai and Hebrew calendars. Other changes: - Clarify that weekdays run Monday=0 to Sunday=6 (#2) - Change Julian converter to use astronomical notation (0 = 1 BCE, -1 = 1 BCE) - Expanded tests 2.0.2 ----- Features: * Add support for Python 3 (#1)convertdate-2.1.3/LICENSE000066400000000000000000000020751334033033100150350ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2014-2016 Neil Freeman Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. convertdate-2.1.3/MANIFEST.in000066400000000000000000000000441334033033100155600ustar00rootroot00000000000000include LICENSE include HISTORY.rst convertdate-2.1.3/Makefile000066400000000000000000000006551334033033100154720ustar00rootroot00000000000000# This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the GPL-v3.0 license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr test: coverage run --source convertdate setup.py test coverage report coverage html deploy: README.rst git push; git push --tags rm -rf dist build python3.5 setup.py sdist bdist_wheel --universal twine upload dist/* convertdate-2.1.3/README.rst000066400000000000000000000127401334033033100155170ustar00rootroot00000000000000=========== convertdate =========== The convertdate package was originally developed as “`Python Date Utils`_” by Phil Schwartz. It had been significantly updated and expanded. Available calendars: - Bahai - Coptic (Alexandrian) - French Republican - Gregorian - Hebrew - Indian Civil - Islamic - Julian - Mayan - Persian - Positivist - Mayan - ISO - Ordinal (day of year) - Dublin day count - Julian day count The ``holidays`` module also provides some useful holiday-calculation, with a focus on North American and Jewish holidays. Installing ---------- ``pip install convertdate`` Or download the package and run ``python setup.py install``. Using ----- :: from convertdate import french_republican from convertdate import hebrew french_republican.from_gregorian(2014, 10, 31) # (223, 2, 1, 9) hebrew.from_gregorian(2014, 10, 31) # (5775, 8, 7) Note that in some calendar systems, the day begins at sundown. Convertdate gives the conversion for noon of the day in question. Each module includes a monthcalendar function, which will generate a calender-like nested list for a year and month (each list of dates runs from Sunday to Saturday) :: hebrew.monthcalendar(5775, 8) # [ # [None, None, None, None, None, None, 1], # [2, 3, 4, 5, 6, 7, 8], # [9, 10, 11, 12, 13, 14, 15], # [16, 17, 18, 19, 20, 21, 22], # [23, 24, 25, 26, 27, 28, 29] # ] julian.monthcalendar(2015, 1) # [ # [None, None, None, 1, 2, 3, 4], # [5, 6, 7, 8, 9, 10, 11], # [12, 13, 14, 15, 16, 17, 18], # [19, 20, 21, 22, 23, 24, 25], # [26, 27, 28, 29, 30, 31, None] # ] Special Options --------------- French Republican ~~~~~~~~~~~~~~~~~ Leap year calculations in the French Republican calendar are a matter of dispute. By default, ``convertdate`` calculates leap years using the autumnal equinox. You can also use one of three more systematic methods proposed over the years. * Romme, a co-creator of the calendar, proposed leap years in years divisible by four, except for years divisible by 100. * Some concordances were drawn up in the 19th century that gave leap years every 4 years, in years that give a remainder of three when divided by four (19, 23, 27, etc...). * Von Mädler proposed leap years in years divisible by four, except for years divisible by 128. You can specify any of these three methods with the method keyword argument in ``french_republican`` conversion functions. :: from convertdate import french_republican # Romme's method french_republican.to_gregorian(20, 1, 1), method='romme') # (1811, 9, 23) # continuous method french_republican.to_gregorian(20, 1, 1), method='continuous') # (1811, 9, 24) # von Mädler's method french_republican.to_gregorian(20, 1, 1), method='madler') # (1811, 9, 23) All the conversion methods correctly assign the leap years implemented while calendar was in use (3, 7, 11). Before the Common Era --------------------- For dates before the Common Era (year 1), ``convertdate`` uses astronomical notation: 1 BC is recorded as 0, 2 BC is -1, etc. This makes arithmatic much easier at the expense of ignoring custom. Note that for dates before 4 CE, ``convertdate`` uses the `proleptic Julian calendar`_. The Julian Calendar was in use from 45 BC, but before 4 CE the leap year leap year pattern was irregular. The `proleptic Gregorian calendar`_ is used for dates before 1582 CE, the year of the Gregorian calendar reform. Holidays -------- North American holidays are the current focus of the ``holidays`` module, but pull requests are welcome. :: from convertdate import holidays # For simplicity, functions in the holidays module return a tuple # In the format (year, month, day) holidays.new_years(2014) # (2014, 1, 1) holidays.memorial_day(2014) # (2014, 5, 26) # USA is default holidays.thanksgiving(2014) # (2014, 11, 27) # But there is a Canadian option for some holidays holidays.thanksgiving(2014, 'canada') # (2014, 10, 13) # Mexican national holidays holidays.natalicio_benito_juarez(2016) # (2016, 3, 21) holidays.dia_revolucion(2016) # (2016, 11, 21) # Some Jewish holidays are included holidays.rosh_hashanah(2014) Utils ----- Convertdate includes some utilities for manipulating and calculating dates. :: from convertdate import utils # Calculate an arbitrary day of the week THUR = 3 APRIL = 4 # 3rd Thursday in April utils.nth_day_of_month(3, THUR, APRIL, 2014) # (2014, 4, 17) utils.nth_day_of_month(5, THUR, APRIL, 2014) # IndexError: No 5th day of month 4 # Use 0 for the first argument to get the last weekday of a month utils.nth_day_of_month(0, THUR, APRIL, 2014) # (2014, 4, 24) Note that when calculating weekdays, convertdate uses the convention of the `calendar` and `time` modules: Monday is 0, Sunday is 6. :: from convertdate import gregorian SUN = 6 day = gregorian.to_jd(2014, 4, 17) nextsunday = utils.next_weekday(SUN, day) gregorian.from_jd(nextsunday) # (2014, 4, 20) Other utility functions: - nearest_weekday - next_or_current_weekday - previous_weekday - previous_or_current_weekday .. _Python Date Utils: http://sourceforge.net/projects/pythondateutil/ .. _proleptic Julian calendar: https://en.wikipedia.org/wiki/Proleptic_Julian_calendar .. _proleptic Gregorian calendar: https://en.wikipedia.org/wiki/Proleptic_Gregorian_calendar convertdate-2.1.3/convertdate/000077500000000000000000000000001334033033100163425ustar00rootroot00000000000000convertdate-2.1.3/convertdate/__init__.py000066400000000000000000000024271334033033100204600ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr # Most of this code is ported from Fourmilab's javascript calendar converter # http://www.fourmilab.ch/documents/calendar/ # which was developed by John Walker # # The algorithms are believed to be derived from the following source: # Meeus, Jean. Astronomical Algorithms . Richmond: Willmann-Bell, 1991. ISBN 0-943396-35-2. # The essential reference for computational positional astronomy. # from . import bahai from . import coptic from . import daycount from . import dublin from . import french_republican from . import gregorian from . import hebrew from . import holidays from . import indian_civil from . import iso from . import islamic from . import julian from . import julianday from . import mayan from . import persian from . import positivist from . import ordinal __version__ = '2.1.3' __all__ = [ 'holidays', 'bahai', 'coptic', 'dublin', 'daycount', 'french_republican', 'gregorian', 'hebrew', 'indian_civil', 'islamic', 'iso', 'julian', 'julianday', 'mayan', 'persian', 'positivist', 'mayan', 'ordinal', ] convertdate-2.1.3/convertdate/babylon.md000066400000000000000000000013401334033033100203100ustar00rootroot00000000000000Babylonian Calendar ------------------- The Babylonian calendar is a lunisolar calender with twelve months of 28 or 29 days. Leap months are inserted in a 19-year cycle. In the system used for most of the calendar's existence, eight months were inserted in each cycle. This 19-year pattern relies on the observation that 236 lunar months occur in very nearly the same time as 19 tropical years (equinox-to-equinox). It's called the Metonic cycle after the Athenian who "discovered" it several hundred years after the Babylonians put it into use. * irregular lunations ** parker and dubberst, and corrections * describe workings of module * analeptic calendar ** 687 year corrections to metonic cycle * roots, reform by nabopolassarconvertdate-2.1.3/convertdate/bahai.py000066400000000000000000000047011334033033100177620ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from calendar import isleap from . import gregorian from .utils import monthcalendarhelper, jwday EPOCH = 2394646.5 EPOCH_GREGORIAN_YEAR = 1844 WEEKDAYS = ("Jamál", "Kamál", "Fidál", "Idál", "Istijlál", "Istiqlál", "Jalál") MONTHS = ("Bahá", "Jalál", "Jamál", "‘Aẓamat", "Núr", "Raḥmat", "Kalimát", "Kamál", "Asmá’", "‘Izzat", "Mashíyyat", "‘Ilm", "Qudrat", "Qawl", "Masá’il", "Sharaf", "Sulṭán", "Mulk", "Ayyám-i-Há", "‘Alá") ENGLISH_MONTHS = ("Splendor", "Glory", "Beauty", "Grandeur", "Light", "Mercy", "Words", "Perfection", "Names", "Might", "Will", "Knowledge", "Power", "Speech", "Questions", "Honour", "Sovereignty", "Dominion", "Days of Há", "Loftiness") def to_jd(year, month, day): '''Determine Julian day from Bahai date''' gy = year - 1 + EPOCH_GREGORIAN_YEAR if month != 20: m = 0 else: if isleap(gy + 1): m = -14 else: m = -15 return gregorian.to_jd(gy, 3, 20) + (19 * (month - 1)) + m + day def from_jd(jd): '''Calculate Bahai date from Julian day''' jd = trunc(jd) + 0.5 g = gregorian.from_jd(jd) gy = g[0] bstarty = EPOCH_GREGORIAN_YEAR if jd <= gregorian.to_jd(gy, 3, 20): x = 1 else: x = 0 # verify this next line... bys = gy - (bstarty + (((gregorian.to_jd(gy, 1, 1) <= jd) and x))) year = bys + 1 days = jd - to_jd(year, 1, 1) bld = to_jd(year, 20, 1) if jd >= bld: month = 20 else: month = trunc(days / 19) + 1 day = int((jd + 1) - to_jd(year, month, 1)) return year, month, day def from_gregorian(year, month, day): return from_jd(gregorian.to_jd(year, month, day)) def to_gregorian(year, month, day): return gregorian.from_jd(to_jd(year, month, day)) def month_length(year, month): if month == 19: if isleap(year + EPOCH_GREGORIAN_YEAR): return 5 else: return 4 else: return 19 def monthcalendar(year, month): start_weekday = jwday(to_jd(year, month, 1)) monthlen = month_length(year, month) return monthcalendarhelper(start_weekday, monthlen) convertdate-2.1.3/convertdate/coptic.py000066400000000000000000000033451334033033100202020ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http:#github.com/fitnr/convertdate # Licensed under the MIT license: # http:#opensource.org/licenses/MIT # Copyright (c) 2017, fitnr from .utils import floor, jwday, monthcalendarhelper from . import gregorian EPOCH = 1825029.5 MONTH_NAMES = ["Thout", "Paopi", "Hathor", "Koiak", "Tobi", "Meshir", "Paremhat", "Paremoude", "Pashons", "Paoni", "Epip", "Mesori", "Pi Kogi Enavot"] DAY_NAMES = ["Tkyriaka", "Pesnau", "Pshoment", "Peftoou", "Ptiou", "Psoou", "Psabbaton"] def is_leap(year): "Determine whether this is a leap year." return year % 4 == 3 or year % 4 == -1 def to_jd(year, month, day): "Retrieve the Julian date equivalent for this date" return day + (month - 1) * 30 + (year - 1) * 365 + floor(year / 4) + EPOCH - 1 def from_jd(jdc): "Create a new date from a Julian date." cdc = floor(jdc) + 0.5 - EPOCH year = floor((cdc - floor((cdc + 366) / 1461)) / 365) + 1 yday = jdc - to_jd(year, 1, 1) month = floor(yday / 30) + 1 day = yday - (month - 1) * 30 + 1 return year, month, day def to_gregorian(year, month, day): return gregorian.from_jd(to_jd(year, month, day)) def from_gregorian(year, month, day): return from_jd(gregorian.to_jd(year, month, day)) def month_length(year, month): if month <= 12: return 30 elif month == 13: if is_leap(year): return 6 else: return 5 else: raise ValueError("Invalid month") def monthcalendar(year, month): start_weekday = jwday(to_jd(year, month, 1)) monthlen = month_length(year, month) return monthcalendarhelper(start_weekday, monthlen) convertdate-2.1.3/convertdate/data/000077500000000000000000000000001334033033100172535ustar00rootroot00000000000000convertdate-2.1.3/convertdate/data/__init__.py000066400000000000000000000000001334033033100213520ustar00rootroot00000000000000convertdate-2.1.3/convertdate/data/french_republican_days.py000066400000000000000000000175431334033033100243300ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr # source: Wikipedia # month 13 is the Sansculottides french_republican_days = { 1: [ u"Raisin", u"Safran", u"Châtaigne", u"Colchique", u"Cheval", u"Balsamine", u"Carotte", u"Amaranthe", u"Panais", u"Cuve", u"Pomme de terre", u"Immortelle", u"Potiron", u"Réséda", u"Âne", u"Belle de nuit", u"Citrouille", u"Sarrasin", u"Tournesol", u"Pressoir", u"Chanvre", u"Pêche", u"Navet", u"Amaryllis", u"Bœuf", u"Aubergine", u"Piment", u"Tomate", u"Orge", u"Tonneau", ], 2: [ u"Pomme", u"Céleri", u"Poire", u"Betterave", u"Oie", u"Héliotrope", u"Figue", u"Scorsonère", u"Alisier", u"Charrue", u"Salsifis", u"Mâcre", u"Topinambour", u"Endive", u"Dindon", u"Chervis", u"Cresson", u"Dentelaire", u"Grenade", u"Herse", u"Bacchante", u"Azerole", u"Garance", u"Orange", u"Faisan", u"Pistache", u"Macjonc", u"Coing", u"Cormier", u"Rouleau", ], 3: [ u"Raiponce", u"Turneps", u"Chicorée", u"Nèfle", u"Cochon", u"Mâche", u"Chou-fleur", u"Miel", u"Genièvre", u"Pioche", u"Cire", u"Raifort", u"Cèdre", u"Sapin", u"Chevreuil", u"Ajonc", u"Cyprès", u"Lierre", u"Sabine", u"Hoyau", u"Érable à sucre", u"Bruyère", u"Roseau", u"Oseille", u"Grillon", u"Pignon", u"Liège", u"Truffe", u"Olive", u"Pelle", ], 4: [ u"Tourbe", u"Houille", u"Bitume", u"Soufre", u"Chien", u"Lave", u"Terre végétale", u"Fumier", u"Salpêtre", u"Fléau", u"Granit", u"Argile", u"Ardoise", u"Grès", u"Lapin", u"Silex", u"Marne", u"Pierre à chaux", u"Marbre", u"Van", u"Pierre à plâtre", u"Sel", u"Fer", u"Cuivre", u"Chat", u"Étain", u"Plomb", u"Zinc", u"Mercure", u"Crible", ], 5: [ u"Lauréole", u"Mousse", u"Fragon", u"Perce-neige", u"Taureau", u"Laurier-thym", u"Amadouvier", u"Mézéréon", u"Peuplier", u"Coignée", u"Ellébore", u"Brocoli", u"Laurier", u"Avelinier", u"Vache", u"Buis", u"Lichen", u"If", u"Pulmonaire", u"Serpette", u"Thlaspi", u"Thimelé", u"Chiendent", u"Trainasse", u"Lièvre", u"Guède", u"Noisetier", u"Cyclamen", u"Chélidoine", u"Traîneau", ], 6: [ u"Tussilage", u"Cornouiller", u"Violier", u"Troène", u"Bouc", u"Asaret", u"Alaterne", u"Violette", u"Marceau", u"Bêche", u"Narcisse", u"Orme", u"Fumeterre", u"Vélar", u"Chèvre", u"Épinard", u"Doronic", u"Mouron", u"Cerfeuil", u"Cordeau", u"Mandragore", u"Persil", u"Cochléaria", u"Pâquerette", u"Thon", u"Pissenlit", u"Sylvie", u"Capillaire", u"Frêne", u"Plantoir", ], 7: [ u"Primevère", u"Platane", u"Asperge", u"Tulipe", u"Poule", u"Bette", u"Bouleau", u"Jonquille", u"Aulne", u"Couvoir", u"Pervenche", u"Charme", u"Morille", u"Hêtre", u"Abeille", u"Laitue", u"Mélèze", u"Ciguë", u"Radis", u"Ruche", u"Gainier", u"Romaine", u"Marronnier", u"Roquette", u"Pigeon", u"Lilas", u"Anémone", u"Pensée", u"Myrtille", u"Greffoir", ], 8: [ u"Rose", u"Chêne", u"Fougère", u"Aubépine", u"Rossignol", u"Ancolie", u"Muguet", u"Champignon", u"Hyacinthe", u"Râteau", u"Rhubarbe", u"Sainfoin", u"Bâton d'or", u"Chamerisier", u"Ver à soie", u"Consoude", u"Pimprenelle", u"Corbeille d'or", u"Arroche", u"Sarcloir", u"Statice", u"Fritillaire", u"Bourrache", u"Valériane", u"Carpe", u"Fusain", u"Civette", u"Buglosse", u"Sénevé", u"Houlette", ], 9: [ u"Luzerne", u"Hémérocalle", u"Trèfle", u"Angélique", u"Canard", u"Mélisse", u"Fromental", u"Martagon", u"Serpolet", u"Faux", u"Fraise", u"Bétoine", u"Pois", u"Acacia", u"Caille", u"Œillet", u"Sureau", u"Pavot", u"Tilleul", u"Fourche", u"Barbeau", u"Camomille", u"Chèvrefeuille", u"Caille-lait", u"Tanche", u"Jasmin", u"Verveine", u"Thym", u"Pivoine", u"Chariot", ], 10: [ u"Seigle", u"Avoine", u"Oignon", u"Véronique", u"Mulet", u"Romarin", u"Concombre", u"Échalote", u"Absinthe", u"Faucille", u"Coriandre", u"Artichaut", u"Girofle", u"Lavande", u"Chamois", u"Tabac", u"Groseille", u"Gesse", u"Cerise", u"Parc", u"Menthe", u"Cumin", u"Haricot", u"Orcanète", u"Pintade", u"Sauge", u"Ail", u"Vesce", u"Blé", u"Chalémie", ], 11: [ u"Épeautre", u"Bouillon blanc", u"Melon", u"Ivraie", u"Bélier", u"Prêle", u"Armoise", u"Carthame", u"Mûre", u"Arrosoir", u"Panic", u"Salicorne", u"Abricot", u"Basilic", u"Brebis", u"Guimauve", u"Lin", u"Amande", u"Gentiane", u"Écluse", u"Carline", u"Câprier", u"Lentille", u"Aunée", u"Loutre", u"Myrte", u"Colza", u"Lupin", u"Coton", u"Moulin", ], 12: [ u"Prune", u"Millet", u"Lycoperdon", u"Escourgeon", u"Saumon", u"Tubéreuse", u"Sucrion", u"Apocyn", u"Réglisse", u"Échelle", u"Pastèque", u"Fenouil", u"Épine vinette", u"Noix", u"Truite", u"Citron", u"Cardère", u"Nerprun", u"Tagette", u"Hotte", u"Églantier", u"Noisette", u"Houblon", u"Sorgho", u"Écrevisse", u"Bigarade", u"Verge d'or", u"Maïs", u"Marron", u"Panier", ], 13: [ u"La Fête de la Vertu", u"La Fête du Génie", u"La Fête du Travail", u"La Fête de l'Opinion", u"La Fête des Récompenses", u"La Fête de la Révolution", ] } convertdate-2.1.3/convertdate/data/positivist.py000066400000000000000000000302531334033033100220450ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- day_names = ( "Prometheus", "Hercules", "Orpheus", "Ulysses", "Lycurgus", "Romulus", "Numa", "Belus", "Sesostris", "Menu", "Cyrus", "Zoroaster", "The Druids", "Buddha", "Fuxi", "Laozi", "Mencius", "Theocrats of Tibet", "Theocrats of Japan", "Manco Cápac", "Confucius", "Abraham", "Samuel", "Solomon", "Isaiah", "St. John the Baptist", "Haroun-al-Raschid", "Muhammad", "Hesiod", "Tyrtéus", "Anacreon", "Pindar", "Sophocles", "Theocritus", "Aeschylus", "Scopas", "Zeuxis", "Ictinus", "Praxiteles", "Lysippus", "Apelles", "Phidias", "Aesop", "Plautus", "Terence", "Phaedrus", "Juvenal", "Lucian", "Aristophanes", "Ennius", "Lucretius", "Horace", "Tibullus", "Ovid", "Lucan", "Virgil", "Anaximander", "Anaximenes", "Heraclitus", "Anaxagoras", "Democritus", "Herodotus", "Thales", "Solon", "Xenophanes", "Empodocles", "Thucydides", "Archytas", "Apollonius of Tyana", "Pythagoras", "Aristippus", "Antisthenes", "Zeno", "Cicero", "Epictetus", "Tacitus", "Socrates", "Xenocrates", "Philo of Alexandria", "St. John the Evangelist", "St. Justin", "St. Clement of Alexandria", "Origen", "Plato", "Theophrastus", "Herophilus", "Erasistratus", "Celsus", "Galen", "Avicenna", "Hippocrates", "Euclid", "Aristéus", "Theodisius of Bithynia", "Hero", "Pappus", "Diophantus", "Apollonius", "Eudoxus", "Pytheas", "Aristarchus", "Eratos-thenes", "Ptolemy", "Albategnius", "Hipparchus", "Varro", "Columella", "Vitruvius", "Strabo", "Frontinus", "Plutarch", "Pliny the Elder", "Miltiades", "Leonidas", "Aristides", "Cimon", "Xenophon", "Phocion", "Themistocles", "Pericles", "Philip", "Demosthenes", "PtolemyLagus", "Philopoemen", "Polybius", "Alexander", "JuniusBrutus", "Camillus", "Fabricius", "Hannibal", "Paulus Aemilius", "Marius", "Scipio", "Augustus", "Vespasian", "Hadrian", "Antonius", "Papinian", "Alexander Severus", "Trajan", "St. Luke", "St. Cyprian", "St. Athanasius", "St. Jerome", "St. Ambrose", "St. Monica", "St. Augustine", "Constantine", "Theodosius", "St. Chrysostom", "St. Genevieve of Paris", "St. Pulcheria", "St. Gregory the Great", "Hildebrand", "St. Benedict", "St. Boniface", "St. Isidore of Seville", "Lanfranc", "Heloise", "the architects of the Middle Ages", "St. Bernard", "St. Francis Xavier", "St. Charles Borromeo", "St. Theresa", "St. Vincent de Paul", "Bourdaloue", "William Penn", "Bossuet", "Theodoric the Great", "Pelayo", "Otho the Great", "St. Henry", "Villers", "Don John of Austria", "Alfred", "Charles Martel", "El Cid", "Richard I", "Joan of Arc", "Albuquerque", "Bayard", "Godfrey", "St. Leo the Great", "Gerbert", "Peter the Hermit", "Suger", "Alexander III", "St. Francis of Assisi", "Innocent III", "St. Clotilde", "St. Bathilda", "St. Stephen of Hungary", "St. Elizabeth of Hungary", "Blanche of Castille", "St. Ferdinand III", "St. Louis", "the Troubadours", "Boccaccio", "Rabelais", "Cervantes", "La Fontain", "Defoe", "Aristo", "Leonardo da Vinci", "Michael Angelo", "Holbein", "Poussin", "Velásquez", "Teniers", "Raphael", "Froissart", "Camoens", "The Spanish Romancers", "Chateaubriand", "Walter Scott", "Manzoni", "Tasso", "Petrarca", "Thomas of Kempis", "Mademoiselle de Lafayette", "Fénélon", "Klopstock", "Byron", "Milton", "Marco Polo", "Jacques Coeur", "Vasco de Gama", "Napier", "Lacaille", "Cook", "Columbus", "Benvenuto Cellini", "Amontons", "Harrison", "Dollond", "Arkwright", "Conté", "Vaucanson", "Stevin", "Mariotte", "Papin", "Black", "Jouffroy", "Dalton", "Watt", "Bernard de Palissy", "Guglielmini", "Duhamel du Monceau", "Saussure", "Coulomb", "Carnot", "Montgolfier", "Lope de Vega", "Moreto", "Rojas", "Otway", "Lessing", "Goethe", "Calderon", "Tirso", "Vondel", "Racine", "Voltaire", "Metastasio", "Schiller", "Corneille", "Almarcon", "Mademoiselle de Motteville", "Mademoiselle de Sévigné", "Lesage", "Mademoiselle deStaal", "Fielding", "Moliere", "Pergolese", "Sacchini", "Gluck", "Beethoven", "Rossini", "Bellini", "Mozart", "Albertus Magnus", "Roger Bacon", "St. Bonaventura", "Ramus", "Montaigne", "Campanella", "St. Thomas Aquinas", "Hobbes", "Pascal", "Locke", "Vauvenargues", "Diderot", "Cabanis", "Lordbacon", "Grotius", "Fontenelle", "Vico", "Fréret", "Montesquieu", "Buffon", "Leibnitz", "Robertson", "Adam Smith", "Kant", "Condercet", "Joseph de Maistre", "Hegel", "Hume", "Marie de Molina", "Cosimo de Medici the Elder", "Philippe de Comines", "Isabella of Castille", "Charles V", "Henry Iv", "Louis Xi", "L'Hôpital", "Barneveldt", "Gustavus Adolphus", "De Witt", "Ruyter", "William III", "William the Silent", "Ximenes", "Sully", "Mazarin", "Colbert", "D'Aranda", "Turgot", "Richelieu", "Sidney", "Franklin", "Washington", "Jefferson", "Bolivar", "Francia", "Cromwell", "Copernicus", "Kepler", "Huyghens", "James Bernouilli", "Bradley", "Volta", "Galileo", "Vieta", "Wallis", "Clairaut", "Euler", "D'Alembert", "Lagrange", "Newton", "Bergmann", "Priestley", "Cavendish", "Guyton Morveau", "Berthollet", "Berzelius", "Lavoisier", "Harvey", "Boerhaave", "Linnaeus", "Haller", "Lamarck", "Broussais", "Gall", "the Dead", "Sainted Women" ) leap_day_replacements = { 0: "Cadmus", 1: "Theseus", 2: "Tiresias", 7: "Semiramus", 12: "Ossian", 19: "Tamehameha", 21: "Joseph", 23: "David", 26: "Abderrahman", 29: "Sappho", 32: "Euripides", 33: "Longus", 42: "Pilpay", 44: "Menander", 60: "Leucippus", 67: "Philolaus", 73: "Pliny the Younger", 74: "Arrian", 80: "St. Irenaeus", 82: "Tertullian", 89: "Averrhoes", 94: "Ctesibius", 98: "Aratus", 99: "Nearchus", 100: "Berosus", 101: "Sosigenes", 103: "Nasreddin", 117: "Epaminondas", 127: "Cincinnatus", 128: "Regulus", 131: "the Gracchi", 133: "Maecenas", 134: "Titus", 135: "Nerva", 136: "Marcus Aurelius", 137: "Ulpian", 138: "Aetius", 140: "St. James", 149: "St. Basil", 151: "Marcian", 154: "St. Anthony", 155: "St. Austin", 156: "St. Bruno", 157: "St. Anselm", 158: "Beatrice", 159: "St. Benezet", 161: "Ignatius Loyola", 162: "Fredrick Borromeo", 163: "St. Catharine of Siena", 164: "Abbé de l'Epée", 165: "Claude Fleury", 166: "George Fox", 170: "Henry the Fowler", 172: "La Valette", 173: "John Sobieski", 176: "Tancred", 177: "Saladin", 178: "Marina", 179: "Sir Walter Raleigh", 182: "Leo IV", 183: "Peter Damian", 185: "St. Eligius", 186: "Becket", 187: "St. Dominic", 190: "St. Mathilda of Tuscany", 191: "Mathias Corvinus", 194: "Alfonso X", 197: "Chaucer", 198: "Swift", 200: "Burns", 201: "Goldsmith", 203: "Titian", 204: "Paul Veronese", 205: "Rembrandt", 206: "Lesueuer", 207: "Murillo", 208: "Rubens", 210: "Joinville", 211: "Spenser", 214: "James Fenimore Cooper", 218: "Louis of Granada & Bunyan", 219: "Mademoiselle de Staël", 220: "St. Francis of Sales", 221: "Gessner", 222: "Élisa Mercœur & Shelly", 224: "Chardin", 225: "Gresham", 226: "Magellan", 227: "Briggs", 228: "Delambre", 229: "Tasman", 232: "Wheatstone", 233: "Pierre Leroy", 234: "Graham", 235: "Jacquard", 238: "Torricelli", 239: "Boyle", 240: "Worcester", 242: "Fulton", 243: "Thilorier", 246: "Riquet", 247: "Bourgelat", 248: "Bouguer", 249: "Borda", 250: "Vauban", 252: "Montalvan", 253: "Guillem de Castro", 254: "Guevara", 263: "Alfieri", 267: "Mademoiselle Roland", 268: "Lady Montagu", 269: "Sterne", 270: "Miss Edgeworth", 271: "Richardson", 273: "Palestrina", 274: "Grétry", 275: "Lully", 276: "Handel", 277: "Weber", 278: "Donizeti", 280: "John of Salisbury", 281: "Raymond Lully", 282: "Joachim", 283: "Nicholas of Cusa", 284: "Erasmus", 285: "Sir Thomas More", 287: "Spinoza", 288: "Giordano Bruno", 289: "Malebranche", 290: "Mademoiselle de Lambert", 291: "Duclos", 292: "George Leroy", 294: "Cujas", 295: "Maupertuis", 296: "Herder", 297: "Wincklemann", 298: "D'Aguesseau", 299: "Oken", 301: "Gibbon", 302: "Dunoyer", 303: "Fichte", 304: "Ferguson", 305: "Bonald", 306: "Sophie Germain", 310: "Guicciardini", 312: "Sixtus V", 323: "Oxenstiern", 324: "Walpole", 325: "Louis XIV", 326: "Pombal", 327: "Campomanes", 329: "Lambert", 330: "Hampden", 331: "Kosciusko", 332: "Madison", 333: "Toussaint L'Ouverture", 336: "Tycho Brahe", 337: "Halley", 338: "Varignon", 339: "John Bernouilli", 340: "Römer", 341: "Sauveur", 343: "Harriot", 344: "Fermat", 345: "Poinsot", 346: "Monge", 347: "Daniel Bernouilli", 348: "Joseph Fourier", 350: "Scheele", 351: "Davy", 353: "Geoffroy", 355: "Ritter", 357: "Charles Bell", 358: "Stahl & Barthez", 359: "Bernard de Jussieu", 360: "Félix Vicq-d'Azyr", 361: "Blainville", 362: "Morgagni", } day_names_leap = [leap_day_replacements.get(i, x) for i, x in enumerate(day_names)] festivals = { (1, 1): "the Great Being", (1, 7): "religion", (1, 14): "history", (1, 21): "nation", (1, 28): "community", (2, 7): "complete marriage", (2, 14): "chaste marriage", (2, 21): "unequal marriage", (2, 28): "subjective marriage", (3, 7): "natural fatherhood", (3, 14): "artificial fatherhood", (3, 21): "spiritual fatherhood", (3, 28): "temporal fatherhood", (4, 7): "natural filiation", (4, 14): "artificial filiation", (4, 21): "spiritual filiation", (4, 28): "temporal filiation", (5, 7): "natural brotherhood", (5, 14): "artificial brotherhood", (5, 21): "spiritual brotherhood", (5, 28): "temporal brotherhood", (6, 7): "complete permanent domesticity", (6, 14): "incomplete permanent domesticity", (6, 21): "complete passing domesticity", (6, 28): "incomplete passing domesticity", (7, 7): "animal gods", (7, 14): "fire gods", (7, 21): "sun gods", (7, 28): "war gods", (8, 7): "castes", (8, 14): "polytheistic arts", (8, 21): "polytheistic theory", (8, 28): "polytheistic society", (9, 7): "monotheistic theology", (9, 14): "Catholocism", (9, 21): "Islam", (9, 28): "metaphysics", (10, 7): "the mother", (10, 14): "the wife", (10, 21): "the daughter", (10, 28): "the sister", (11, 7): "artistic intellectuals", (11, 14): "scientific intellectuals", (11, 21): "secondary intellectual providence", (11, 28): "the elderly", (12, 7): "the bank", (12, 14): "commerce", (12, 21): "manufacturing", (12, 28): "agriculture", (13, 7): "inventors", (13, 14): "emotional labor", (13, 21): "meditation", (13, 28): "passive labor", (14, 1): "the Dead", (14, 2): "Sainted Women", } convertdate-2.1.3/convertdate/daycount.py000066400000000000000000000022021334033033100205360ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from . import gregorian from . import julianday from . import julian class DayCount(object): '''A day count converter for the given epoch (in terms of Julian Day Count)''' def __init__(self, epoch): self.epoch = epoch def to_gregorian(self, dc): return gregorian.from_jd(self.to_jd(dc)) def from_gregorian(self, year, month, day): return self.from_jd(gregorian.to_jd(year, month, day)) def to_jd(self, dc): return dc + self.epoch def from_jd(self, jdc): return jdc - self.epoch def from_julian(self, year, month, day): return self.from_jd(julian.to_jd(year, month, day)) def to_julian(self, dc): return julian.from_jd(self.to_jd(dc)) def to_datetime(self, dc): return julianday.to_datetime(self.to_jd(dc)) def from_datetime(self, dt): return self.from_jd(julianday.from_datetime(dt)) convertdate-2.1.3/convertdate/dublin.py000066400000000000000000000012461334033033100201740ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr '''Convert to and from the Dublin day count''' from . import daycount EPOCH = 2415020 # Julian Day Count for Dublin Count 0 _dublin = daycount.DayCount(EPOCH) to_gregorian = _dublin.to_gregorian from_gregorian = _dublin.from_gregorian to_jd = _dublin.to_jd from_jd = _dublin.from_jd from_julian = _dublin.from_julian to_julian = _dublin.to_julian to_datetime = _dublin.to_datetime from_datetime = _dublin.from_datetime convertdate-2.1.3/convertdate/french_republican.py000066400000000000000000000223211334033033100223650ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from . import dublin, gregorian from .data.french_republican_days import french_republican_days import ephem # julian day (1792, 9, 22) EPOCH = 2375839.5 YEAR_EPOCH = 1791. DAYS_IN_YEAR = 365. MOIS = [ u'Vendémiaire', u'Brumaire', u'Frimaire', u'Nivôse', u'Pluviôse', u'Ventôse', u'Germinal', u'Floréal', u'Prairial', u'Messidor', u'Thermidor', u'Fructidor', u'Sansculottides' ] LEAP_CYCLE_DAYS = 1461. # 365 * 4 + 1 LEAP_CYCLE_YEARS = 4. # methods: # 4 (concordance rule): leap every four years: 3, 7, 11, 15, ... etc # 100 (Romme's rule): leap every 4th and 400th year, but not 100th: 20, 24, ... 96, 104, ... 396, 400, ... # 128 (von Mädler's rule): leap every 4th but not 128th: 20, 24, ... 124, 132, ... # equinox [default]: use calculation of the equinox to determine date, never returns a leap year def leap(year, method=None): ''' Determine if this is a leap year in the FR calendar using one of three methods: 4, 100, 128 (every 4th years, every 4th or 400th but not 100th, every 4th but not 128th) ''' method = method or 'equinox' if year in (3, 7, 11): return True elif year < 15: return False if method in (4, 'continuous') or (year <= 16 and method in (128, 'madler', 4, 'continuous')): return year % 4 == 3 elif method in (100, 'romme'): return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0 elif method in (128, 'madler'): return year % 4 == 0 and year % 128 != 0 elif method == 'equinox': # Is equinox on 366th day after (year, 1, 1) startjd = to_jd(year, 1, 1, method='equinox') if premier_da_la_annee(startjd + 367) - startjd == 366.0: return True else: raise ValueError("Unknown leap year method. Try: continuous, romme, madler or equinox") return False def premier_da_la_annee(jd): '''Determine the year in the French revolutionary calendar in which a given Julian day falls. Returns Julian day number containing fall equinox (first day of the FR year)''' p = ephem.previous_fall_equinox(dublin.from_jd(jd)) previous = trunc(dublin.to_jd(p) - 0.5) + 0.5 if previous + 364 < jd: # test if current day is the equinox if the previous equinox was a long time ago n = ephem.next_fall_equinox(dublin.from_jd(jd)) nxt = trunc(dublin.to_jd(n) - 0.5) + 0.5 if nxt <= jd: return nxt return previous def to_jd(year, month, day, method=None): '''Obtain Julian day from a given French Revolutionary calendar date.''' method = method or 'equinox' if day < 1 or day > 30: raise ValueError("Invalid day for this calendar") if month > 13: raise ValueError("Invalid month for this calendar") if month == 13 and day > 5 + leap(year, method=method): raise ValueError("Invalid day for this month in this calendar") if method == 'equinox': return _to_jd_equinox(year, month, day) else: return _to_jd_schematic(year, month, day, method) def _to_jd_schematic(year, month, day, method): '''Calculate JD using various leap-year calculation methods''' y0, y1, y2, y3, y4, y5 = 0, 0, 0, 0, 0, 0 intercal_cycle_yrs, over_cycle_yrs, leap_suppression_yrs = None, None, None # Use the every-four-years method below year 16 (madler) or below 15 (romme) if ((method in (100, 'romme') and year < 15) or (method in (128, 'madler') and year < 17)): method = 4 if method in (4, 'continuous'): # Leap years: 15, 19, 23, ... y5 = -365 elif method in (100, 'romme'): year = year - 13 y5 = DAYS_IN_YEAR * 12 + 3 leap_suppression_yrs = 100. leap_suppression_days = 36524 # leap_cycle_days * 25 - 1 intercal_cycle_yrs = 400. intercal_cycle_days = 146097 # leap_suppression_days * 4 + 1 over_cycle_yrs = 4000. over_cycle_days = 1460969 # intercal_cycle_days * 10 - 1 elif method in (128, 'madler'): year = year - 17 y5 = DAYS_IN_YEAR * 16 + 4 leap_suppression_days = 46751 # 32 * leap_cycle_days - 1 leap_suppression_yrs = 128 else: raise ValueError("Unknown leap year method. Try: continuous, romme, madler or equinox") if over_cycle_yrs: y0 = trunc(year / over_cycle_yrs) * over_cycle_days year = year % over_cycle_yrs # count intercalary cycles in days (400 years long or None) if intercal_cycle_yrs: y1 = trunc(year / intercal_cycle_yrs) * intercal_cycle_days year = year % intercal_cycle_yrs # count leap suppresion cycles in days (100 or 128 years long) if leap_suppression_yrs: y2 = trunc(year / leap_suppression_yrs) * leap_suppression_days year = year % leap_suppression_yrs y3 = trunc(year / LEAP_CYCLE_YEARS) * LEAP_CYCLE_DAYS year = year % LEAP_CYCLE_YEARS # Adjust 'year' by one to account for lack of year 0 y4 = year * DAYS_IN_YEAR yj = y0 + y1 + y2 + y3 + y4 + y5 mj = (month - 1) * 30 return EPOCH + yj + mj + day - 1 def _to_jd_equinox(an, mois, jour): day_of_adr = (30 * (mois - 1)) + (jour - 1) equinoxe = ephem.next_fall_equinox(str(an + YEAR_EPOCH)) return trunc(dublin.to_jd(equinoxe.real) - 0.5) + 0.5 + day_of_adr def from_jd(jd, method=None): '''Calculate date in the French Revolutionary calendar from Julian day. The five or six "sansculottides" are considered a thirteenth month in the results of this function.''' method = method or 'equinox' if method == 'equinox': return _from_jd_equinox(jd) else: return _from_jd_schematic(jd, method) def _from_jd_schematic(jd, method): '''Convert from JD using various leap-year calculation methods''' if jd < EPOCH: raise ValueError("Can't convert days before the French Revolution") # days since Epoch J = trunc(jd) + 0.5 - EPOCH y0, y1, y2, y3, y4, y5 = 0, 0, 0, 0, 0, 0 intercal_cycle_days = leap_suppression_days = over_cycle_days = None # Use the every-four-years method below year 17 if (J <= DAYS_IN_YEAR * 12 + 3 and method in (100, 'romme')) or (J <= DAYS_IN_YEAR * 17 + 4 and method in (128, 'madler')): method = 4 # set p and r in Hatcher algorithm if method in (4, 'continuous'): # Leap years: 15, 19, 23, ... # Reorganize so that leap day is last day of cycle J = J + 365 y5 = - 1 elif method in (100, 'romme'): # Year 15 is not a leap year # Year 16 is leap, then multiples of 4, not multiples of 100, yes multiples of 400 y5 = 12 J = J - DAYS_IN_YEAR * 12 - 3 leap_suppression_yrs = 100. leap_suppression_days = 36524 # LEAP_CYCLE_DAYS * 25 - 1 intercal_cycle_yrs = 400. intercal_cycle_days = 146097 # leap_suppression_days * 4 + 1 over_cycle_yrs = 4000. over_cycle_days = 1460969 # intercal_cycle_days * 10 - 1 elif method in (128, 'madler'): # Year 15 is a leap year, then year 20 and multiples of 4, not multiples of 128 y5 = 16 J = J - DAYS_IN_YEAR * 16 - 4 leap_suppression_yrs = 128 leap_suppression_days = 46751 # 32 * leap_cycle_days - 1 else: raise ValueError("Unknown leap year method. Try: continuous, romme, madler or equinox") if over_cycle_days: y0 = trunc(J / over_cycle_days) * over_cycle_yrs J = J % over_cycle_days if intercal_cycle_days: y1 = trunc(J / intercal_cycle_days) * intercal_cycle_yrs J = J % intercal_cycle_days if leap_suppression_days: y2 = trunc(J / leap_suppression_days) * leap_suppression_yrs J = J % leap_suppression_days y3 = trunc(J / LEAP_CYCLE_DAYS) * LEAP_CYCLE_YEARS if J % LEAP_CYCLE_DAYS == LEAP_CYCLE_DAYS - 1: J = 1460 else: J = J % LEAP_CYCLE_DAYS # 0 <= J <= 1460 # J needs to be 365 here on leap days ONLY y4 = trunc(J / DAYS_IN_YEAR) if J == DAYS_IN_YEAR * 4: y4 = y4 - 1 J = 365.0 else: J = J % DAYS_IN_YEAR year = y0 + y1 + y2 + y3 + y4 + y5 month = trunc(J / 30.) J = J - month * 30 return year + 1, month + 1, trunc(J) + 1 def _from_jd_equinox(jd): '''Calculate the FR day using the equinox as day 1''' jd = trunc(jd) + 0.5 equinoxe = premier_da_la_annee(jd) an = gregorian.from_jd(equinoxe)[0] - YEAR_EPOCH mois = trunc((jd - equinoxe) / 30.) + 1 jour = int((jd - equinoxe) % 30) + 1 return (an, mois, jour) def decade(jour): return trunc(jour / 100.) + 1 def day_name(month, day): return french_republican_days[month][day - 1] def from_gregorian(year, month, day, method=None): return from_jd(gregorian.to_jd(year, month, day), method=method) def to_gregorian(an, mois, jour, method=None): return gregorian.from_jd(to_jd(an, mois, jour, method=method)) def format(an, mois, jour): return "{0} {1} {2}".format(jour, MOIS[mois - 1], an) convertdate-2.1.3/convertdate/gregorian.py000066400000000000000000000060541334033033100206760ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from calendar import isleap, monthrange from .utils import floor, monthcalendarhelper, jwday EPOCH = 1721425.5 INTERCALATION_CYCLE_YEARS = 400 INTERCALATION_CYCLE_DAYS = 146097 LEAP_SUPPRESSION_YEARS = 100 LEAP_SUPPRESSION_DAYS = 36524 LEAP_CYCLE_YEARS = 4 LEAP_CYCLE_DAYS = 1461 YEAR_DAYS = 365 HAVE_30_DAYS = (4, 6, 9, 11) HAVE_31_DAYS = (1, 3, 5, 7, 8, 10, 12) def legal_date(year, month, day): '''Check if this is a legal date in the Gregorian calendar''' if month == 2: daysinmonth = 29 if isleap(year) else 28 else: daysinmonth = 30 if month in HAVE_30_DAYS else 31 if not (0 < day <= daysinmonth): raise ValueError("Month {} doesn't have a day {}".format(month, day)) return True def to_jd2(year, month, day): '''Gregorian to Julian Day Count for years between 1801-2099''' # http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html legal_date(year, month, day) if month <= 2: year = year - 1 month = month + 12 a = floor(year / 100) b = floor(a / 4) c = 2 - a + b e = floor(365.25 * (year + 4716)) f = floor(30.6001 * (month + 1)) return c + day + e + f - 1524.5 def to_jd(year, month, day): legal_date(year, month, day) if month <= 2: leap_adj = 0 elif isleap(year): leap_adj = -1 else: leap_adj = -2 return ( EPOCH - 1 + (YEAR_DAYS * (year - 1)) + floor((year - 1) / LEAP_CYCLE_YEARS) + (-floor((year - 1) / LEAP_SUPPRESSION_YEARS)) + floor((year - 1) / INTERCALATION_CYCLE_YEARS) + floor((((367 * month) - 362) / 12) + leap_adj + day) ) def from_jd(jd): '''Return Gregorian date in a (Y, M, D) tuple''' wjd = floor(jd - 0.5) + 0.5 depoch = wjd - EPOCH quadricent = floor(depoch / INTERCALATION_CYCLE_DAYS) dqc = depoch % INTERCALATION_CYCLE_DAYS cent = floor(dqc / LEAP_SUPPRESSION_DAYS) dcent = dqc % LEAP_SUPPRESSION_DAYS quad = floor(dcent / LEAP_CYCLE_DAYS) dquad = dcent % LEAP_CYCLE_DAYS yindex = floor(dquad / YEAR_DAYS) year = ( quadricent * INTERCALATION_CYCLE_YEARS + cent * LEAP_SUPPRESSION_YEARS + quad * LEAP_CYCLE_YEARS + yindex ) if not (cent == 4 or yindex == 4): year += 1 yearday = wjd - to_jd(year, 1, 1) leap = isleap(year) if yearday < 58 + leap: leap_adj = 0 elif leap: leap_adj = 1 else: leap_adj = 2 month = floor((((yearday + leap_adj) * 12) + 373) / 367) day = int(wjd - to_jd(year, month, 1)) + 1 return (year, month, day) def month_length(year, month): return monthrange(year, month)[1] def monthcalendar(year, month): start_weekday = jwday(to_jd(year, month, 1)) monthlen = month_length(year, month) return monthcalendarhelper(start_weekday, monthlen) convertdate-2.1.3/convertdate/hebrew.py000066400000000000000000000102211334033033100201640ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from . import gregorian from .utils import jwday, monthcalendarhelper EPOCH = 347995.5 HEBREW_YEAR_OFFSET = 3760 # Hebrew months NISAN = 1 IYYAR = 2 SIVAN = 3 TAMMUZ = 4 AV = 5 ELUL = 6 TISHRI = 7 HESHVAN = 8 KISLEV = 9 TEVETH = 10 SHEVAT = 11 ADAR = 12 VEADAR = 13 def leap(year): # Is a given Hebrew year a leap year ? return (((year * 7) + 1) % 19) < 7 def year_months(year): '''How many months are there in a Hebrew year (12 = normal, 13 = leap)''' if leap(year): return 13 else: return 12 def delay_1(year): '''Test for delay of start of new year and to avoid''' # Sunday, Wednesday, and Friday as start of the new year. months = trunc(((235 * year) - 234) / 19) parts = 12084 + (13753 * months) day = trunc((months * 29) + parts / 25920) if ((3 * (day + 1)) % 7) < 3: day += 1 return day def delay_2(year): '''Check for delay in start of new year due to length of adjacent years''' last = delay_1(year - 1) present = delay_1(year) next_ = delay_1(year + 1) if next_ - present == 356: return 2 elif present - last == 382: return 1 else: return 0 def year_days(year): '''How many days are in a Hebrew year ?''' return to_jd(year + 1, 7, 1) - to_jd(year, 7, 1) def month_days(year, month): '''How many days are in a given month of a given year''' if month > 13: raise ValueError("Incorrect month index") # First of all, dispose of fixed-length 29 day months if month in (IYYAR, TAMMUZ, ELUL, TEVETH, VEADAR): return 29 # If it's not a leap year, Adar has 29 days if month == ADAR and not leap(year): return 29 # If it's Heshvan, days depend on length of year if month == HESHVAN and (year_days(year) % 10) != 5: return 29 # Similarly, Kislev varies with the length of year if month == KISLEV and (year_days(year) % 10) == 3: return 29 # Nope, it's a 30 day month return 30 def to_jd(year, month, day): months = year_months(year) jd = EPOCH + delay_1(year) + delay_2(year) + day + 1 if month < 7: for mon in range(7, months + 1): jd += month_days(year, mon) for mon in range(1, month): jd += month_days(year, mon) else: for mon in range(7, month): jd += month_days(year, mon) return int(jd) + 0.5 def from_jd(jd): jd = trunc(jd) + 0.5 count = trunc(((jd - EPOCH) * 98496.0) / 35975351.0) year = count - 1 i = count while jd >= to_jd(i, 7, 1): i += 1 year += 1 if jd < to_jd(year, 1, 1): first = 7 else: first = 1 month = i = first while jd > to_jd(year, i, month_days(year, i)): i += 1 month += 1 day = int(jd - to_jd(year, month, 1)) + 1 return (year, month, day) def to_jd_gregorianyear(gregorianyear, hebrew_month, hebrew_day): # gregorian year is either 3760 or 3761 years less than hebrew year # we'll first try 3760 if conversion to gregorian isn't the same # year that was passed to this method, then it must be 3761. for y in (gregorianyear + HEBREW_YEAR_OFFSET, gregorianyear + HEBREW_YEAR_OFFSET + 1): jd = to_jd(y, hebrew_month, hebrew_day) gd = gregorian.from_jd(jd) if gd[0] == gregorianyear: break else: gd = None if not gd: # should never occur, but just incase... raise ValueError("Could not determine gregorian year") # tuple: (y, m, d) return (gd[0], gd[1], gd[2]) def from_gregorian(year, month, day): return from_jd(gregorian.to_jd(year, month, day)) def to_gregorian(year, month, day): return gregorian.from_jd(to_jd(year, month, day)) def monthcalendar(year, month): start_weekday = jwday(to_jd(year, month, 1)) monthlen = month_days(year, month) return monthcalendarhelper(start_weekday, monthlen) convertdate-2.1.3/convertdate/holidays.py000066400000000000000000000215061334033033100205340ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr import time import calendar from math import trunc from .utils import nth_day_of_month from . import hebrew # weekdays MON = 0 TUE = 1 WED = 2 THU = 3 FRI = 4 SAT = 5 SUN = 6 # months JAN = 1 FEB = 2 MAR = 3 APR = 4 MAY = 5 JUN = 6 JUL = 7 AUG = 8 SEP = 9 OCT = 10 NOV = 11 DEC = 12 def new_years(year): '''Jan 1st''' return (year, JAN, 1) def martin_luther_king_day(year): '''third monday in January''' return nth_day_of_month(3, MON, JAN, year) def lincolns_birthday(year): '''Feb 12''' return (year, FEB, 12) def valentines_day(year): '''feb 14th''' return (year, FEB, 14) def washingtons_birthday(year): '''Feb 22''' return (year, FEB, 22) def presidents_day(year): '''3rd Monday of Feb''' return nth_day_of_month(3, MON, FEB, year) def pulaski_day(year): '''1st monday in March''' return nth_day_of_month(1, MON, MAR, year) def easter(year): '''Calculate western easter''' # formula taken from http://aa.usno.navy.mil/faq/docs/easter.html c = trunc(year / 100) n = year - 19 * trunc(year / 19) k = trunc((c - 17) / 25) i = c - trunc(c / 4) - trunc((c - k) / 3) + (19 * n) + 15 i = i - 30 * trunc(i / 30) i = i - trunc(i / 28) * (1 - trunc(i / 28) * trunc(29 / (i + 1)) * trunc((21 - n) / 11)) j = year + trunc(year / 4) + i + 2 - c + trunc(c / 4) j = j - 7 * trunc(j / 7) l = i - j month = 3 + trunc((l + 40) / 44) day = l + 28 - 31 * trunc(month / 4) return year, int(month), int(day) def may_day(year): return (year, MAY, 1) def mothers_day(year): '''2nd Sunday in May''' return nth_day_of_month(2, SUN, MAY, year) def memorial_day(year): '''last Monday in May''' return nth_day_of_month(0, MON, MAY, year) def fathers_day(year): '''3rd Sunday in June''' return nth_day_of_month(3, SUN, JUN, year) def flag_day(year): '''June 14th''' return (year, JUN, 14) def independence_day(year, observed=None): '''July 4th''' day = 4 if observed: if calendar.weekday(year, JUL, 4) == SAT: day = 3 if calendar.weekday(year, JUL, 4) == SUN: day = 5 return (year, JUL, day) def labor_day(year): '''first Monday in Sep''' return nth_day_of_month(1, MON, SEP, year) def columbus_day(year, country='usa'): '''in USA: 2nd Monday in Oct Elsewhere: Oct 12''' if country == 'usa': return nth_day_of_month(2, MON, OCT, year) else: return (year, OCT, 12) def halloween(year): '''Oct 31''' return (year, OCT, 31) def election_day(year): '''1st Tues in Nov''' return nth_day_of_month(1, TUE, NOV, year) def veterans_day(year): '''Nov 11''' return (year, NOV, 11) def rememberance_day(year): return veterans_day(year) def armistice_day(year): return veterans_day(year) def thanksgiving(year, country='usa'): '''USA: last Thurs. of November, Canada: 2nd Mon. of October''' if country == 'usa': if year in [1940, 1941]: return nth_day_of_month(3, THU, NOV, year) elif year == 1939: return nth_day_of_month(4, THU, NOV, year) else: return nth_day_of_month(0, THU, NOV, year) if country == 'canada': return nth_day_of_month(2, MON, OCT, year) def christmas_eve(year): '''24th of December''' return (year, DEC, 24) def christmas(year): '''25th of December''' return (year, DEC, 25) def new_years_eve(year): '''Dec 31st''' return (year, DEC, 31) # Jewish holidays begins the sunset before the first (secular) day of the holiday # With the eve option set, the day of this sunset is returned # without the option, the (secular) day is returned def hanukkah(year, eve=None): year, month, day = hebrew.to_jd_gregorianyear(year, hebrew.KISLEV, 25) if eve: day = day - 1 return year, month, day def purim(year, eve=None): if not hebrew.leap(year + hebrew.HEBREW_YEAR_OFFSET): year, month, day = hebrew.to_jd_gregorianyear(year, hebrew.ADAR, 14) else: year, month, day = hebrew.to_jd_gregorianyear(year, hebrew.VEADAR, 14) if eve: day = day - 1 return year, month, day def rosh_hashanah(year, eve=None): year, month, day = hebrew.to_jd_gregorianyear(year, hebrew.TISHRI, 1) if eve: day = day - 1 return year, month, day def yom_kippur(year, eve=None): year, month, day = hebrew.to_jd_gregorianyear(year, hebrew.TISHRI, 10) if eve: day = day - 1 return year, month, day def passover(year, eve=None): year, month, day = hebrew.to_jd_gregorianyear(year, hebrew.NISAN, 15) if eve: day = day - 1 return year, month, day def shavuot(year, eve=None): year, month, day = hebrew.to_jd_gregorianyear(year, hebrew.SIVAN, 6) if eve: day = day - 1 return year, month, day def sukkot(year, eve=None): year, month, day = hebrew.to_jd_gregorianyear(year, hebrew.TISHRI, 15) if eve: day = day - 1 return year, month, day # Mexican holidays def dia_constitucion(year, observed=True): if observed: return nth_day_of_month(1, MON, FEB, year) else: return (year, FEB, 5) def natalicio_benito_juarez(year, observed=True): if observed: return nth_day_of_month(3, MON, MAR, year) else: return (year, MAR, 21) def dia_independencia(year): return year, SEP, 16 def dia_revolucion(year): return nth_day_of_month(3, MON, NOV, year) class Holidays(object): def __init__(self, year=None): self.year = year or time.localtime().tm_year def set_year(self, year): self.year = year def __repr__(self): return 'Holidays({})'.format(self.year) # the holidays... @property def christmas(self): return christmas(self.year) @property def christmas_eve(self): return christmas_eve(self.year) @property def thanksgiving(self, country='usa'): return thanksgiving(self.year, country) @property def new_years(self): return new_years(self.year) @property def new_years_eve(self): return new_years_eve(self.year) @property def independence_day(self): return independence_day(self.year, observed=True) @property def flag_day(self): return flag_day(self.year) @property def election_day(self): return election_day(self.year) @property def presidents_day(self): return presidents_day(self.year) @property def washingtons_birthday(self): return washingtons_birthday(self.year) @property def lincolns_birthday(self): return lincolns_birthday(self.year) @property def memorial_day(self): return memorial_day(self.year) @property def labor_day(self): return labor_day(self.year) @property def columbus_day(self, country='usa'): return columbus_day(self.year, country) @property def veterans_day(self): return veterans_day(self.year) @property def valentines_day(self): return valentines_day(self.year) @property def halloween(self): return halloween(self.year) @property def mothers_day(self): return mothers_day(self.year) @property def fathers_day(self): return fathers_day(self.year) @property def pulaski_day(self): return pulaski_day(self.year) @property def easter(self): return easter(self.year) @property def martin_luther_king_day(self): return martin_luther_king_day(self.year) @property def hanukkah(self): return hanukkah(self.year, eve=False) @property def purim(self): return purim(self.year, eve=False) @property def rosh_hashanah(self): return rosh_hashanah(self.year, eve=False) @property def yom_kippur(self): return yom_kippur(self.year, eve=False) @property def passover(self): return passover(self.year, eve=False) @property def shavuot(self): return shavuot(self.year, eve=False) @property def sukkot(self): return sukkot(self.year, eve=False) @property def dia_constitucion(self): return dia_constitucion(self.year, observed=True) @property def natalicio_benito_juarez(self): return natalicio_benito_juarez(self.year, observed=True) @property def dia_independencia(self): return dia_independencia(self.year) @property def dia_revolucion(self): return dia_revolucion(self.year) if __name__ == '__main__': holiday = Holidays(time.localtime().tm_year) convertdate-2.1.3/convertdate/indian_civil.py000066400000000000000000000060011334033033100213410ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from calendar import isleap from . import gregorian from .utils import jwday, monthcalendarhelper # 0 = Sunday WEEKDAYS = ( "Ravivāra", "Somavāra", "Maṅgalavāra", "Budhavāra", "Guruvāra", "Śukravāra", "Śanivāra", ) MONTHS = ( "Chaitra", "Vaishākha", "Jyēshtha", "Āshādha", "Shrāvana", "Bhādrapada", "Āshwin", "Kārtika", "Mārgashīrsha", "Pausha", "Māgha", "Phālguna", ) HAVE_31_DAYS = (2, 3, 4, 5, 6) HAVE_30_DAYS = (7, 8, 9, 10, 11, 12) SAKA_EPOCH = 78 def to_jd(year, month, day): '''Obtain Julian day for Indian Civil date''' gyear = year + 78 leap = isleap(gyear) # // Is this a leap year ? # 22 - leap = 21 if leap, 22 non-leap start = gregorian.to_jd(gyear, 3, 22 - leap) if leap: Caitra = 31 else: Caitra = 30 if month == 1: jd = start + (day - 1) else: jd = start + Caitra m = month - 2 m = min(m, 5) jd += m * 31 if month >= 8: m = month - 7 jd += m * 30 jd += day - 1 return jd def from_jd(jd): '''Calculate Indian Civil date from Julian day Offset in years from Saka era to Gregorian epoch''' start = 80 # Day offset between Saka and Gregorian jd = trunc(jd) + 0.5 greg = gregorian.from_jd(jd) # Gregorian date for Julian day leap = isleap(greg[0]) # Is this a leap year? # Tentative year in Saka era year = greg[0] - SAKA_EPOCH # JD at start of Gregorian year greg0 = gregorian.to_jd(greg[0], 1, 1) yday = jd - greg0 # Day number (0 based) in Gregorian year if leap: Caitra = 31 # Days in Caitra this year else: Caitra = 30 if yday < start: # Day is at the end of the preceding Saka year year -= 1 yday += Caitra + (31 * 5) + (30 * 3) + 10 + start yday -= start if yday < Caitra: month = 1 day = yday + 1 else: mday = yday - Caitra if (mday < (31 * 5)): month = trunc(mday / 31) + 2 day = (mday % 31) + 1 else: mday -= 31 * 5 month = trunc(mday / 30) + 7 day = (mday % 30) + 1 return (year, month, int(day)) def from_gregorian(year, month, day): return from_jd(gregorian.to_jd(year, month, day)) def to_gregorian(year, month, day): return gregorian.from_jd(to_jd(year, month, day)) def month_length(year, month): if month in HAVE_31_DAYS or (month == 1 and isleap(year - SAKA_EPOCH)): return 31 return 30 def monthcalendar(year, month): start_weekday = jwday(to_jd(year, month, 1)) monthlen = month_length(year, month) return monthcalendarhelper(start_weekday, monthlen) convertdate-2.1.3/convertdate/islamic.py000066400000000000000000000032001334033033100203300ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from .utils import ceil, jwday, monthcalendarhelper from . import gregorian EPOCH = 1948439.5 WEEKDAYS = ("al-'ahad", "al-'ithnayn", "ath-thalatha'", "al-'arb`a'", "al-khamis", "al-jum`a", "as-sabt") HAS_29_DAYS = (2, 4, 6, 8, 10) HAS_30_DAYS = (1, 3, 5, 7, 9, 11) def leap(year): '''Is a given year a leap year in the Islamic calendar''' return (((year * 11) + 14) % 30) < 11 def to_jd(year, month, day): '''Determine Julian day count from Islamic date''' return (day + ceil(29.5 * (month - 1)) + (year - 1) * 354 + trunc((3 + (11 * year)) / 30) + EPOCH) - 1 def from_jd(jd): '''Calculate Islamic date from Julian day''' jd = trunc(jd) + 0.5 year = trunc(((30 * (jd - EPOCH)) + 10646) / 10631) month = min(12, ceil((jd - (29 + to_jd(year, 1, 1))) / 29.5) + 1) day = int(jd - to_jd(year, month, 1)) + 1 return (year, month, day) def from_gregorian(year, month, day): return from_jd(gregorian.to_jd(year, month, day)) def to_gregorian(year, month, day): return gregorian.from_jd(to_jd(year, month, day)) def month_length(year, month): if month in HAS_30_DAYS or (month == 12 and leap(year)): return 30 return 29 def monthcalendar(year, month): start_weekday = jwday(to_jd(year, month, 1)) monthlen = month_length(year, month) return monthcalendarhelper(start_weekday, monthlen) convertdate-2.1.3/convertdate/iso.py000066400000000000000000000031571334033033100175140ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from calendar import isleap from .utils import jwday, n_weeks from . import gregorian, ordinal MON = 0 TUE = 1 WED = 2 THU = 3 FRI = 4 SAT = 5 SUN = 6 def to_jd(year, week, day): '''Return Julian day count of given ISO year, week, and day''' return day + n_weeks(SUN, gregorian.to_jd(year - 1, 12, 28), week) def from_jd(jd): '''Return tuple of ISO (year, week, day) for Julian day''' year = gregorian.from_jd(jd)[0] day = jwday(jd) + 1 dayofyear = ordinal.from_jd(jd)[1] week = trunc((dayofyear - day + 10) / 7) # Reset year if week < 1: week = weeks_per_year(year - 1) year = year - 1 # Check that year actually has 53 weeks elif week == 53 and weeks_per_year(year) != 53: week = 1 year = year + 1 return year, week, day def weeks_per_year(year): '''Number of ISO weeks in a year''' # 53 weeks: any year starting on Thursday and any leap year starting on Wednesday jan1 = jwday(gregorian.to_jd(year, 1, 1)) if jan1 == THU or (jan1 == WED and isleap(year)): return 53 else: return 52 def from_gregorian(year, month, day): return from_jd(gregorian.to_jd(year, month, day)) def to_gregorian(year, week, day): return gregorian.from_jd(to_jd(year, week, day)) def format(year, week, day): return "{}-W{:02}-{}".format(year, week, day) convertdate-2.1.3/convertdate/julian.py000066400000000000000000000047431334033033100202060ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from .utils import jwday, monthcalendarhelper from .gregorian import to_jd as gregorian_to_jd, from_jd as gregorian_from_jd J0000 = 1721424.5 # Julian date of Gregorian epoch: 0000-01-01 J1970 = 2440587.5 # Julian date at Unix epoch: 1970-01-01 JMJD = 2400000.5 # Epoch of Modified Julian Date system JULIAN_EPOCH = 1721423.5 J2000 = 2451545.0 # Julian day of J2000 epoch JULIANCENTURY = 36525.0 # Days in Julian century HAVE_30_DAYS = (4, 6, 9, 11) HAVE_31_DAYS = (1, 3, 5, 7, 8, 10, 12) def leap(year): if year % 4 and year > 0: return 0 else: return 3 def month_length(year, month): if month == 2: daysinmonth = 29 if leap(year) else 28 else: daysinmonth = 30 if month in HAVE_30_DAYS else 31 return daysinmonth def legal_date(year, month, day): '''Check if this is a legal date in the Julian calendar''' daysinmonth = month_length(year, month) if not (0 < day <= daysinmonth): raise ValueError("Month {} doesn't have a day {}".format(month, day)) return True def from_jd(jd): '''Calculate Julian calendar date from Julian day''' jd += 0.5 z = trunc(jd) a = z b = a + 1524 c = trunc((b - 122.1) / 365.25) d = trunc(365.25 * c) e = trunc((b - d) / 30.6001) if trunc(e < 14): month = e - 1 else: month = e - 13 if trunc(month > 2): year = c - 4716 else: year = c - 4715 day = b - d - trunc(30.6001 * e) return (year, month, day) def to_jd(year, month, day): '''Convert to Julian day using astronomical years (0 = 1 BC, -1 = 2 BC)''' legal_date(year, month, day) # Algorithm as given in Meeus, Astronomical Algorithms, Chapter 7, page 61 if month <= 2: year -= 1 month += 12 return (trunc((365.25 * (year + 4716))) + trunc((30.6001 * (month + 1))) + day) - 1524.5 def from_gregorian(year, month, day): return from_jd(gregorian_to_jd(year, month, day)) def to_gregorian(year, month, day): return gregorian_from_jd(to_jd(year, month, day)) def monthcalendar(year, month): start_weekday = jwday(to_jd(year, month, 1)) monthlen = month_length(year, month) return monthcalendarhelper(start_weekday, monthlen) convertdate-2.1.3/convertdate/julianday.py000066400000000000000000000033061334033033100206760ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from datetime import datetime from . import gregorian from . import julian from pytz import utc def to_datetime(jdc): '''Return a datetime for the input floating point Julian Day Count''' year, month, day = gregorian.from_jd(jdc) # in jdc: 0.0 = noon, 0.5 = midnight # the 0.5 changes it to 0.0 = midnight, 0.5 = noon frac = (jdc + 0.5) % 1 hours = int(24 * frac) mfrac = frac * 24 - hours mins = int(60 * round(mfrac, 6)) sfrac = mfrac * 60 - mins secs = int(60 * round(sfrac, 6)) msfrac = sfrac * 60 - secs # down to ms, which are 1/1000 of a second ms = int(1000 * round(msfrac, 6)) return datetime(year, month, day, int(hours), int(mins), int(secs), int(ms), tzinfo=utc) def from_datetime(dt): # take account of offset (if there isn't one, act like it's utc) try: dt = dt + dt.utcoffset() except TypeError: # Assuming UTC pass jdc = gregorian.to_jd(dt.year, dt.month, dt.day) hfrac = dt.hour / 24. mfrac = round(dt.minute / (24. * 60), 5) sfrac = round(dt.second / (24. * 60 * 60), 5) msfrac = dt.microsecond / (24. * 60 * 60 * 1000) return jdc + hfrac + mfrac + sfrac + msfrac def to_gregorian(jdc): return gregorian.from_jd(jdc) def from_gregorian(year, month, day): return gregorian.to_jd(year, month, day) def to_julian(jdc): return julian.from_jd(jdc) def from_julian(year, month, day): return julian.to_jd(year, month, day) convertdate-2.1.3/convertdate/mayan.py000066400000000000000000000202351334033033100200230ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc import itertools from .utils import amod from . import gregorian EPOCH = 584282.5 HAAB_MONTHS = ["Pop", "Wo'", "Zip", "Sotz'", "Sek", "Xul", "Yaxk'in'", "Mol", "Ch'en", "Yax", "Sak'", "Keh", "Mak", "K'ank'in", "Muwan'", "Pax", "K'ayab", "Kumk'u", "Wayeb'"] HAAB_TRANSLATIONS = [ "Mat", "Frog", "Red", "Bat", "Bee", "Dog", "First Sun", "Water", "Cave", "Green", "White", "Red", "Encloser", "Yellow Sun", "Screech Owl", "Planting Time", "Turtle", "Ripe Corn", "Nameless"] TZOLKIN_NAMES = ["Imix'", "Ik'", "Ak'b'al", "K'an", "Chikchan", "Kimi", "Manik'", "Lamat", "Muluk", "Ok", "Chuwen", "Eb'", "B'en", "Ix", "Men", "K'ib'", "Kab'an", "Etz'nab'", "Kawak", "Ajaw"] TZOLKIN_TRANSLATIONS = ['Water', 'Wind', 'Darkness', 'Net', 'Feathered Serpent', 'Death', 'Deer', 'Seed', 'Jade', 'Dog', 'Thread', 'Path', 'Maize', 'Tiger', 'Bird', 'Will', 'Wisdom', 'Obsidian Knife', 'Thunder', 'Sun'] def to_jd(baktun, katun, tun, uinal, kin): '''Determine Julian day from Mayan long count''' return EPOCH + (baktun * 144000) + (katun * 7200) + (tun * 360) + (uinal * 20) + kin def from_jd(jd): '''Calculate Mayan long count from Julian day''' d = jd - EPOCH baktun = trunc(d / 144000) d = (d % 144000) katun = trunc(d / 7200) d = (d % 7200) tun = trunc(d / 360) d = (d % 360) uinal = trunc(d / 20) kin = int((d % 20)) return (baktun, katun, tun, uinal, kin) def to_gregorian(baktun, katun, tun, uinal, kin): jd = to_jd(baktun, katun, tun, uinal, kin) return gregorian.from_jd(jd) def from_gregorian(year, month, day): jd = gregorian.to_jd(year, month, day) return from_jd(jd) def to_haab(jd): '''Determine Mayan Haab "month" and day from Julian day''' # Number of days since the start of the long count lcount = trunc(jd) + 0.5 - EPOCH # Long Count begins 348 days after the start of the cycle day = (lcount + 348) % 365 count = day % 20 month = trunc(day / 20) return int(count), HAAB_MONTHS[month] def to_tzolkin(jd): '''Determine Mayan Tzolkin "month" and day from Julian day''' lcount = trunc(jd) + 0.5 - EPOCH day = amod(lcount + 4, 13) name = amod(lcount + 20, 20) return int(day), TZOLKIN_NAMES[int(name) - 1] def lc_to_haab(baktun, katun, tun, uinal, kin): jd = to_jd(baktun, katun, tun, uinal, kin) return to_haab(jd) def lc_to_tzolkin(baktun, katun, tun, uinal, kin): jd = to_jd(baktun, katun, tun, uinal, kin) return to_tzolkin(jd) def lc_to_haab_tzolkin(baktun, katun, tun, uinal, kin): jd = to_jd(baktun, katun, tun, uinal, kin) dates = to_tzolkin(jd) + to_haab(jd) return "{0} {1} {2} {3}".format(*dates) def translate_haab(h): return dict(list(zip(HAAB_MONTHS, HAAB_TRANSLATIONS))).get(h) def translate_tzolkin(tz): return dict(list(zip(TZOLKIN_NAMES, TZOLKIN_TRANSLATIONS))).get(tz) def _haab_count(day, month): '''Return the count of the given haab in the cycle. e.g. 0 Pop == 1, 5 Wayeb' == 365''' if day < 0 or day > 19: raise IndexError("Invalid day number") try: i = HAAB_MONTHS.index(month) except ValueError: raise ValueError("'{0}' is not a valid Haab' month".format(month)) return min(i * 20, 360) + day def _tzolkin_from_count(count): number = amod(count, 13) name = TZOLKIN_NAMES[count % 20 - 1] return number, name def _tzolkin_count(day, name): if day < 1 or day > 13: raise IndexError("Invalid day number") days = set(x + day for x in range(0, 260, 13)) try: n = 1 + TZOLKIN_NAMES.index(name) except ValueError: raise ValueError("'{0}' is not a valid Tzolk'in day name".format(name)) names = set(y + n for y in range(0, 260, 20)) return days.intersection(names).pop() def tzolkin_generator(number=None, name=None): '''For a given tzolkin name/number combination, return a generator that gives cycle, starting with the input''' # By default, it will start at the beginning number = number or 13 name = name or "Ajaw" if number > 13: raise ValueError("Invalid day number") if name not in TZOLKIN_NAMES: raise ValueError("Invalid day name") count = _tzolkin_count(number, name) ranged = itertools.chain(list(range(count, 260)), list(range(1, count))) for i in ranged: yield _tzolkin_from_count(i) def longcount_generator(baktun, katun, tun, uinal, kin): '''Generate long counts, starting with input''' j = to_jd(baktun, katun, tun, uinal, kin) while True: yield from_jd(j) j = j + 1 def next_haab(month, jd): '''For a given haab month and a julian day count, find the next start of that month on or after the JDC''' if jd < EPOCH: raise IndexError("Input day is before Mayan epoch.") hday, hmonth = to_haab(jd) if hmonth == month: days = 1 - hday else: count1 = _haab_count(hday, hmonth) count2 = _haab_count(1, month) # Find number of days between haab of given jd and desired haab days = (count2 - count1) % 365 # add in the number of days and return new jd return jd + days def next_tzolkin(tzolkin, jd): '''For a given tzolk'in day, and a julian day count, find the next occurrance of that tzolk'in after the date''' if jd < EPOCH: raise IndexError("Input day is before Mayan epoch.") count1 = _tzolkin_count(*to_tzolkin(jd)) count2 = _tzolkin_count(*tzolkin) add_days = (count2 - count1) % 260 return jd + add_days def next_tzolkin_haab(tzolkin, haab, jd): '''For a given haab-tzolk'in combination, and a Julian day count, find the next occurrance of the combination after the date''' # get H & T of input jd, and their place in the 18,980 day cycle haabcount = _haab_count(*to_haab(jd)) haab_desired_count = _haab_count(*haab) # How many days between the input day and the desired day? haab_days = (haab_desired_count - haabcount) % 365 possible_haab = set(h + haab_days for h in range(0, 18980, 365)) tzcount = _tzolkin_count(*to_tzolkin(jd)) tz_desired_count = _tzolkin_count(*tzolkin) # How many days between the input day and the desired day? tzolkin_days = (tz_desired_count - tzcount) % 260 possible_tz = set(t + tzolkin_days for t in range(0, 18980, 260)) try: return possible_tz.intersection(possible_haab).pop() + jd except KeyError: raise IndexError("That Haab'-Tzolk'in combination isn't possible") def month_length(month): """Not the actual length of the month, but accounts for the 5 unlucky/nameless days""" if month == "Wayeb'": return 5 else: return 20 def haab_monthcalendar(baktun=None, katun=None, tun=None, uinal=None, kin=None, jdc=None): '''For a given long count, return a calender of the current haab month, divided into tzolkin "weeks"''' if not jdc: jdc = to_jd(baktun, katun, tun, uinal, kin) haab_number, haab_month = to_haab(jdc) first_j = jdc - haab_number + 1 tzolkin_start_number, tzolkin_start_name = to_tzolkin(first_j) gen_longcount = longcount_generator(*from_jd(first_j)) gen_tzolkin = tzolkin_generator(tzolkin_start_number, tzolkin_start_name) # 13 day long tzolkin 'weeks' lpad = tzolkin_start_number - 1 rpad = 13 - (tzolkin_start_number + 19 % 13) monlen = month_length(haab_month) days = [None] * lpad + list(range(1, monlen + 1)) + rpad * [None] def g(x, generate): if x is None: return None return next(generate) return [[(k, g(k, gen_tzolkin), g(k, gen_longcount)) for k in days[i:i + 13]] for i in range(0, len(days), 13)] def haab_monthcalendar_prospective(haabmonth, jdc): '''Give the monthcalendar for the next occurance of given haab month after jdc''' return haab_monthcalendar(jdc=next_haab(haabmonth, jdc)) convertdate-2.1.3/convertdate/ordinal.py000066400000000000000000000021201334033033100203370ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from calendar import isleap from . import gregorian def to_jd(year, dayofyear): '''Return Julian day count of given ISO year, and day of year''' return gregorian.to_jd(year, 1, 1) + dayofyear - 1 def from_jd(jd): return from_gregorian(*gregorian.from_jd(jd)) def from_gregorian(year, month, day): m = month + 1 if m <= 3: m = m + 12 leap = isleap(year) t = (trunc(30.6 * m) + day - 122 + 59 + leap) % (365 + leap) return year, t def to_gregorian(year, dayofyear): leap = isleap(year) if dayofyear < 59 + leap: leap_adj = 0 elif leap: leap_adj = 1 else: leap_adj = 2 month = trunc((((dayofyear - 1 + leap_adj) * 12) + 373) / 367) startofmonth = from_gregorian(year, month, 1) return year, month, dayofyear - startofmonth[1] + 1 convertdate-2.1.3/convertdate/persian.py000066400000000000000000000045751334033033100203700ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from math import trunc from .utils import ceil, jwday, monthcalendarhelper from . import gregorian EPOCH = 1948320.5 WEEKDAYS = ("Doshanbeh", "Seshhanbeh", "Chaharshanbeh", "Panjshanbeh", "Jomeh", "Shanbeh", "Yekshanbeh") HAS_31_DAYS = (1, 2, 3, 4, 5, 6) HAS_30_DAYS = (7, 8, 9, 10, 11) def leap(year): '''Is a given year a leap year in the Persian calendar ?''' if year > 0: y = 474 else: y = 473 return ((((((year - y % 2820) + 474) + 38) * 682) % 2816) < 682) def to_jd(year, month, day): '''Determine Julian day from Persian date''' if year >= 0: y = 474 else: y = 473 epbase = year - y epyear = 474 + (epbase % 2820) if month <= 7: m = (month - 1) * 31 else: m = (month - 1) * 30 + 6 return day + m + trunc(((epyear * 682) - 110) / 2816) + (epyear - 1) * 365 + trunc(epbase / 2820) * 1029983 + (EPOCH - 1) def from_jd(jd): '''Calculate Persian date from Julian day''' jd = trunc(jd) + 0.5 depoch = jd - to_jd(475, 1, 1) cycle = trunc(depoch / 1029983) cyear = (depoch % 1029983) if cyear == 1029982: ycycle = 2820 else: aux1 = trunc(cyear / 366) aux2 = cyear % 366 ycycle = trunc(((2134 * aux1) + (2816 * aux2) + 2815) / 1028522) + aux1 + 1 year = ycycle + (2820 * cycle) + 474 if (year <= 0): year -= 1 yday = (jd - to_jd(year, 1, 1)) + 1 if yday <= 186: month = ceil(yday / 31) else: month = ceil((yday - 6) / 30) day = int(jd - to_jd(year, month, 1)) + 1 return (year, month, day) def from_gregorian(year, month, day): return from_jd(gregorian.to_jd(year, month, day)) def to_gregorian(year, month, day): return gregorian.from_jd(to_jd(year, month, day)) def month_length(year, month): if month in HAS_30_DAYS or (month == 12 and leap(year)): return 30 elif month in HAS_31_DAYS: return 31 return 29 def monthcalendar(year, month): start_weekday = jwday(to_jd(year, month, 1)) monthlen = month_length(year, month) return monthcalendarhelper(start_weekday, monthlen) convertdate-2.1.3/convertdate/positivist.py000066400000000000000000000075641334033033100211450ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from calendar import isleap from . import gregorian from .utils import floor from .data import positivist as data ''' Convert between Gregorian/Julian Day and Comte's Positivist calendar. The Positivist calendar has 13 months and one or two festival days. Festival days are given as the fourteenth month. The Gregorian date 1789-01-01 is Positivist 0001-01-01. ''' # Positivist calendar has 13 28-day months and one festival day EPOCH = 2374479.5 YEAR_EPOCH = 1789 DAYS_IN_YEAR = 365 MONTHS = ( 'Moses', 'Homer', 'Aristotle', 'Archimedes', 'Caesar', 'Saint Paul', 'Charlemagne', 'Dante', 'Gutenberg', 'Shakespeare', 'Descartes', 'Frederic', 'Bichat', '' ) def legal_date(year, month, day): '''Checks if a given date is a legal positivist date''' try: assert year >= 1 assert 0 < month <= 14 assert 0 < day <= 28 if month == 14: if isleap(year + YEAR_EPOCH - 1): assert day <= 2 else: assert day == 1 except AssertionError: raise ValueError("Invalid Positivist date: ({}, {}, {})".format(year, month, day)) return True def to_jd(year, month, day): '''Convert a Positivist date to Julian day count.''' legal_date(year, month, day) gyear = year + YEAR_EPOCH - 1 return ( gregorian.EPOCH - 1 + (365 * (gyear - 1)) + floor((gyear - 1) / 4) + (-floor((gyear - 1) / 100)) + floor((gyear - 1) / 400) + (month - 1) * 28 + day ) def from_jd(jd): '''Convert a Julian day count to Positivist date.''' try: assert jd >= EPOCH except AssertionError: raise ValueError('Invalid Julian day') depoch = floor(jd - 0.5) + 0.5 - gregorian.EPOCH quadricent = floor(depoch / gregorian.INTERCALATION_CYCLE_DAYS) dqc = depoch % gregorian.INTERCALATION_CYCLE_DAYS cent = floor(dqc / gregorian.LEAP_SUPPRESSION_DAYS) dcent = dqc % gregorian.LEAP_SUPPRESSION_DAYS quad = floor(dcent / gregorian.LEAP_CYCLE_DAYS) dquad = dcent % gregorian.LEAP_CYCLE_DAYS yindex = floor(dquad / gregorian.YEAR_DAYS) year = ( quadricent * gregorian.INTERCALATION_CYCLE_YEARS + cent * gregorian.LEAP_SUPPRESSION_YEARS + quad * gregorian.LEAP_CYCLE_YEARS + yindex ) if yindex == 4: yearday = 365 year = year - 1 else: yearday = ( depoch - quadricent * gregorian.INTERCALATION_CYCLE_DAYS - cent * gregorian.LEAP_SUPPRESSION_DAYS - quad * gregorian.LEAP_CYCLE_DAYS - yindex * gregorian.YEAR_DAYS ) month = floor(yearday / 28) return (year - YEAR_EPOCH + 2, month + 1, int(yearday - (month * 28)) + 1) def from_gregorian(year, month, day): return from_jd(gregorian.to_jd(year, month, day)) def to_gregorian(year, month, day): return gregorian.from_jd(to_jd(year, month, day)) def dayname(year, month, day): ''' Give the name of the month and day for a given date. Returns: tuple month_name, day_name ''' legal_date(year, month, day) yearday = (month - 1) * 28 + day if isleap(year + YEAR_EPOCH - 1): dname = data.day_names_leap[yearday - 1] else: dname = data.day_names[yearday - 1] return MONTHS[month - 1], dname def weekday(day): ''' Gives the weekday (0=Monday) of a positivist month and day. Note that the festival month does not have a day. ''' return (day % 7) - 1 def festival(month, day): ''' Gives the festival day for a month and day. Returns None if inapplicable. ''' return data.festivals.get((month, day)) convertdate-2.1.3/convertdate/utils.py000066400000000000000000000061271334033033100200620ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr import math import calendar TROPICALYEAR = 365.24219878 # Mean solar tropical year def ceil(x): return int(math.ceil(x)) def floor(x): return int(math.floor(x)) def amod(a, b): '''Modulus function which returns numerator if modulus is zero''' modded = int(a % b) return b if modded is 0 else modded # Sane people of the world, use calendar.weekday! def jwday(j): '''Calculate day of week from Julian day''' return math.trunc((j + 0.5)) % 7 def weekday_before(weekday, jd): return jd - jwday(jd - weekday) # @param weekday Day of week desired, 0 = Monday # @param jd Julian date to begin search # @param direction 1 = next weekday, -1 = last weekday # @param offset Offset from jd to begin search def search_weekday(weekday, jd, direction, offset): '''Determine the Julian date for the next or previous weekday''' return weekday_before(weekday, jd + (direction * offset)) # Utility weekday functions, just wrappers for search_weekday def nearest_weekday(weekday, jd): return search_weekday(weekday, jd, 1, 3) def next_weekday(weekday, jd): return search_weekday(weekday, jd, 1, 7) def next_or_current_weekday(weekday, jd): return search_weekday(weekday, jd, 1, 6) def previous_weekday(weekday, jd): return search_weekday(weekday, jd, -1, 1) def previous_or_current_weekday(weekday, jd): return search_weekday(weekday, jd, 1, 0) def n_weeks(weekday, jd, nthweek): j = 7 * nthweek if nthweek > 0: j += previous_weekday(weekday, jd) else: j += next_weekday(weekday, jd) return j def monthcalendarhelper(start_weekday, month_length): end_weekday = start_weekday + (month_length - 1) % 7 lpad = (start_weekday + 1) % 7 rpad = (5 - end_weekday % 7) % 6 days = [None] * lpad + list(range(1, 1 + month_length)) + rpad * [None] return [days[i:i + 7] for i in range(0, len(days), 7)] def nth_day_of_month(n, weekday, month, year): """ Return (year, month, day) tuple that represents nth weekday of month in year. If n==0, returns last weekday of month. Weekdays: Monday=0 """ if not (0 <= n <= 5): raise IndexError("Nth day of month must be 0-5. Received: {}".format(n)) if not (0 <= weekday <= 6): raise IndexError("Weekday must be 0-6") firstday, daysinmonth = calendar.monthrange(year, month) # Get first WEEKDAY of month first_weekday_of_kind = 1 + (weekday - firstday) % 7 if n == 0: # find last weekday of kind, which is 5 if these conditions are met, else 4 if first_weekday_of_kind in [1, 2, 3] and first_weekday_of_kind + 28 < daysinmonth: n = 5 else: n = 4 day = first_weekday_of_kind + ((n - 1) * 7) if day > daysinmonth: raise IndexError("No {}th day of month {}".format(n, month)) return (year, month, day) convertdate-2.1.3/setup.py000066400000000000000000000032541334033033100155420ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- # This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the MIT license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr from setuptools import setup try: readme = open('README.rst').read() except IOError: readme = '' with open('convertdate/__init__.py') as i: version = next(r for r in i.readlines() if '__version__' in r).split('=')[1].strip('"\' \n') setup( name="convertdate", version=version, description=("Converts between Gregorian dates and other calendar systems." "Calendars included: Baha'i, French Republican, Hebrew, " "Indian Civil, Islamic, ISO, Julian, Mayan and Persian."), long_description=readme, author="Neil Freeman", license='MIT', author_email="contact@fakeisthenewreal.org", url="https://github.com/fitnr/convertdate", packages=[ "convertdate", "convertdate.data" ], test_suite='tests', zip_safe=True, classifiers=[ 'Programming Language :: Python', 'Programming Language :: Python :: 2', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Programming Language :: Python :: 3.6', 'Topic :: Religion', 'Topic :: Scientific/Engineering :: Astronomy', 'Operating System :: OS Independent', 'License :: OSI Approved :: MIT License' ], install_requires=[ 'ephem>=3.7.5.3, <3.8', 'pytz>=2014.10, < 2020' ] ) convertdate-2.1.3/tests/000077500000000000000000000000001334033033100151665ustar00rootroot00000000000000convertdate-2.1.3/tests/__init__.py000066400000000000000000000006141334033033100173000ustar00rootroot00000000000000# Most of this code is ported from Fourmilab's javascript calendar converter # http://www.fourmilab.ch/documents/calendar/ # which was developed by John Walker # # The algorithms are believed to be derived from the following source: # Meeus, Jean. Astronomical Algorithms . Richmond: Willmann-Bell, 1991. ISBN 0-943396-35-2. # The essential reference for computational positional astronomy. # convertdate-2.1.3/tests/test_french_republican.py000066400000000000000000000271201334033033100222520ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import unittest import time from convertdate import gregorian from convertdate import french_republican as fr year_starts = [ ((1, 1, 1), (1792, 9, 22)), ((2, 1, 1), (1793, 9, 22)), ((3, 1, 1), (1794, 9, 22)), ((4, 1, 1), (1795, 9, 23)), ((5, 1, 1), (1796, 9, 22)), ((6, 1, 1), (1797, 9, 22)), ((7, 1, 1), (1798, 9, 22)), ((8, 1, 1), (1799, 9, 23)), ((9, 1, 1), (1800, 9, 23)), ((10, 1, 1), (1801, 9, 23)), ((11, 1, 1), (1802, 9, 23)), ((12, 1, 1), (1803, 9, 24)), ((13, 1, 1), (1804, 9, 23)), ((14, 1, 1), (1805, 9, 23)), ] leaps = [ ((3, 13, 6), (1795, 9, 22)), ((7, 13, 6), (1799, 9, 22)), ((11, 13, 6), (1803, 9, 23)), ] romme = [ ((15, 1, 1), (1806, 9, 23)), ((15, 13, 5), (1807, 9, 22)), ((16, 1, 1), (1807, 9, 23)), ((16, 13, 6), (1808, 9, 22)), ((17, 1, 1), (1808, 9, 23)), ((17, 13, 5), (1809, 9, 22)), ((18, 1, 1), (1809, 9, 23)), ((19, 1, 1), (1810, 9, 23)), ((20, 1, 1), (1811, 9, 23)), ((20, 13, 6), (1812, 9, 22)), ((222, 1, 1), (2013, 9, 22)), ((223, 1, 1), (2014, 9, 22)), ((225, 1, 1), (2016, 9, 22)), ] continuous = [ ((15, 1, 1), (1806, 9, 23)), ((15, 13, 5), (1807, 9, 22)), ((15, 13, 6), (1807, 9, 23)), ((16, 1, 1), (1807, 9, 24)), ((17, 1, 1), (1808, 9, 23)), ((18, 1, 1), (1809, 9, 23)), ((19, 1, 1), (1810, 9, 23)), ((19, 13, 6), (1811, 9, 23)), ((20, 1, 1), (1811, 9, 24)), ((220, 1, 1), (2011, 9, 25)), ((221, 1, 1), (2012, 9, 24)), ((222, 1, 1), (2013, 9, 24)), ((223, 1, 1), (2014, 9, 24)), ((223, 13, 6), (2015, 9, 24)), ((224, 1, 1), (2015, 9, 25)), ((225, 1, 1), (2016, 9, 24)), ] madler = [ ((15, 1, 1), (1806, 9, 23)), ((15, 13, 6), (1807, 9, 23)), ((16, 1, 1), (1807, 9, 24)), ((16, 13, 5), (1808, 9, 22)), ((17, 1, 1), (1808, 9, 23)), ((18, 1, 1), (1809, 9, 23)), ((18, 13, 5), (1810, 9, 22)), ((19, 1, 1), (1810, 9, 23)), ((19, 13, 5), (1811, 9, 22)), ((20, 1, 1), (1811, 9, 23)), ((20, 13, 6), (1812, 9, 22)), ((222, 1, 1), (2013, 9, 23)), ((223, 1, 1), (2014, 9, 23)), ((224, 1, 1), (2015, 9, 23)), ((224, 13, 6), (2016, 9, 22)), ((225, 1, 1), (2016, 9, 23)) ] class TestFrenchRepublican(unittest.TestCase): def setUp(self): self.tm = time.localtime() self.gregoriandate = (self.tm[0], self.tm[1], self.tm[2]) self.jd = gregorian.to_jd(self.gregoriandate[0], self.gregoriandate[1], self.gregoriandate[2]) self.x = gregorian.to_jd(2016, 2, 29) self.j = gregorian.to_jd(2015, 9, 24) # around the autumnal equinox self.start = 2457285 def test_french_republican(self): assert self.jd == fr.to_jd(*fr.from_jd(self.jd)) assert fr.from_gregorian(2014, 6, 14) == (222, 9, 26) assert (2014, 6, 14) == fr.to_gregorian(222, 9, 26) assert (3, 13, 6) == fr.from_gregorian(1795, 9, 22) for jd in range(2378822, 2488395, 2000): self.assertEqual(jd + 0.5, gregorian.to_jd(*gregorian.from_jd(jd + 0.5))) def test_french_republican_leap(self): self.assertTrue(fr.leap(3)) self.assertTrue(fr.leap(3, 'madler')) self.assertTrue(fr.leap(3, 'romme')) self.assertTrue(fr.leap(3, 'continuous')) self.assertTrue(fr.leap(7)) self.assertTrue(fr.leap(7, 'madler')) self.assertTrue(fr.leap(7, 'romme')) self.assertTrue(fr.leap(7, 'continuous')) self.assertTrue(fr.leap(11)) self.assertTrue(fr.leap(11, 'madler')) self.assertTrue(fr.leap(11, 'romme')) self.assertTrue(fr.leap(11, 'continuous')) self.assertFalse(fr.leap(4)) self.assertFalse(fr.leap(14)) self.assertTrue(fr.leap(15)) self.assertTrue(fr.leap(15, 'madler')) self.assertFalse(fr.leap(15, 'romme')) self.assertTrue(fr.leap(15, 'continuous')) self.assertTrue(fr.leap(20)) self.assertTrue(fr.leap(20, 'madler')) self.assertTrue(fr.leap(20, 'romme')) self.assertFalse(fr.leap(20, 'continuous')) self.assertFalse(fr.leap(23)) self.assertFalse(fr.leap(23, 'madler')) self.assertFalse(fr.leap(23, 'romme')) self.assertTrue(fr.leap(23, 'continuous')) self.assertRaises(ValueError, fr.leap, 100, method='foo') def test_french_republican_decade(self): self.assertEqual(fr.decade(1), 1) def test_french_republican_format(self): self.assertEqual(fr.format(8, 2, 18), '18 Brumaire 8') def test_french_republican_to_jd_errors(self): self.assertRaises(ValueError, fr.to_jd, 100, 1, 0) self.assertRaises(ValueError, fr.to_jd, 100, 1, 31) self.assertRaises(ValueError, fr.to_jd, 100, 14, 1) self.assertRaises(ValueError, fr.to_jd, 4, 13, 6) self.assertRaises(ValueError, fr.to_jd, 100, 12, 1, method='foo') def test_french_republican_from_jd_errors(self): self.assertRaises(ValueError, fr.from_gregorian, 1789, 1, 1, 'romme') def test_french_republican_start_of_years_from_gregorian_equinoctal(self): for f, g in year_starts: self.assertEqual(f, fr.from_gregorian(*g)) def test_french_republican_start_of_years_to_gregorian_equinoctal(self): for f, g in year_starts: self.assertEqual(g, fr.to_gregorian(*f)) def test_french_republican_leap_days_from_gregorian_equinoctal(self): for f, g in leaps: self.assertEqual(f, fr.from_gregorian(*g)) def test_french_republican_leap_days_to_gregorian_equinoctal(self): for f, g in leaps: self.assertEqual(g, fr.to_gregorian(*f)) # Madler (128) def test_french_republican_leap_days_from_gregorian_madler(self): for f, g in leaps: self.assertEqual(f, fr.from_gregorian(*g, method='madler')) def test_french_republican_leap_days_to_gregorian_madler(self): for f, g in leaps: self.assertEqual(g, fr.to_gregorian(*f, method='madler')) def test_french_republican_schematic_madler_to_gregorian(self): for f, g in year_starts: self.assertEqual(g, fr.to_gregorian(*f, method=128)) for f, g in madler: self.assertEqual(g, fr.to_gregorian(*f, method=128)) def test_french_republican_schematic_madler_from_gregorian(self): for f, g in year_starts: self.assertEqual(g, fr.to_gregorian(*f, method=128)) for f, g in madler: self.assertEqual(f, fr.from_gregorian(*g, method=128)) def test_french_republican_schematic_madler(self): self.assertEqual(self.j, fr.to_jd(*fr.from_jd(self.j, method=128), method=128)) self.assertEqual(self.x, fr.to_jd(*fr.from_jd(self.x, method=128), method=128)) self.assertEqual(self.jd, fr.to_jd(*fr.from_jd(self.jd, method=128), method=128)) # # Romme (100) def test_french_republican_leap_days_from_gregorian_romme(self): for f, g in leaps: self.assertEqual(f, fr.from_gregorian(*g, method=100)) def test_french_republican_leap_days_to_gregorian_romme(self): for f, g in leaps: self.assertEqual(g, fr.to_gregorian(*f, method=100)) def test_french_republican_schematic_romme_to_gregorian(self): for f, g in year_starts: self.assertEqual(g, fr.to_gregorian(*f, method=100)) for f, g in romme: self.assertEqual(g, fr.to_gregorian(*f, method='romme')) def test_french_republican_schematic_romme_from_gregorian(self): for f, g in year_starts: self.assertEqual(f, fr.from_gregorian(*g, method='romme')) for f, g in romme: self.assertEqual(f, fr.from_gregorian(*g, method=100)) def test_french_republican_schematic_romme(self): self.assertEqual(self.gregoriandate, fr.to_gregorian( *fr.from_gregorian(*self.gregoriandate, method=100), method=100)) self.assertEqual(self.jd, fr.to_jd(*fr.from_jd(self.jd, method='romme'), method=100)) self.assertEqual(self.x, fr.to_jd(*fr.from_jd(self.x, method=100), method=100)) assert self.j == fr.to_jd(*fr.from_jd(self.j, method=100), method=100) # Continuous (4) def test_french_republican_leap_days_from_gregorian_continuous(self): for f, g in leaps: self.assertEqual(f, fr.from_gregorian(*g, method=4)) def test_french_republican_leap_days_to_gregorian_continuous(self): for f, g in leaps: self.assertEqual(g, fr.to_gregorian(*f, method=4)) def test_french_republican_schematic_continuous_to_gregorian(self): for f, g in year_starts: self.assertEqual(g, fr.to_gregorian(*f, method=4)) for f, g in continuous: self.assertEqual(g, fr.to_gregorian(*f, method='continuous')) def test_french_republican_schematic_continuous_from_gregorian(self): self.assertEqual((16, 1, 1), fr.from_gregorian(1807, 9, 24, method='continuous')) for f, g in year_starts: self.assertEqual(f, fr.from_gregorian(*g, method=4)) for f, g in continuous: self.assertEqual(f, fr.from_gregorian(*g, method=4)) def test_french_republican_schematic_continuous(self): self.assertEqual(gregorian.from_jd(self.jd), fr.to_gregorian(*fr.from_jd(self.jd, method=4), method=4)) self.assertEqual(self.x, fr.to_jd(*fr.from_jd(self.x, method=4), method=4)) assert self.j == fr.to_jd(*fr.from_jd(self.j, method='continuous'), method=4) def test_french_republican_famous_dates(self): self.assertEqual(gregorian.to_jd(1793, 9, 22), fr.to_jd(2, 1, 1)) # 9 Thermidor II self.assertEqual(gregorian.to_jd(1794, 7, 27), fr.to_jd(2, 11, 9)) # 18 Brumaire An VIII assert gregorian.to_jd(1799, 11, 9) == fr.to_jd(8, 2, 18) assert fr.to_jd(2, 9, 22) == gregorian.to_jd(1794, 6, 10) assert fr.to_jd(4, 1, 13) == gregorian.to_jd(1795, 10, 5) assert fr.to_gregorian(5, 12, 18) == (1797, 9, 4) assert fr.to_jd(6, 8, 22) == gregorian.to_jd(1798, 5, 11) assert (2, 9, 22) == fr.from_gregorian(1794, 6, 10) assert (4, 1, 13) == fr.from_gregorian(1795, 10, 5) assert (5, 12, 18) == fr.from_gregorian(1797, 9, 4) assert (6, 8, 22) == fr.from_gregorian(1798, 5, 11) # Coup of 30 Prairial VII self.assertEqual(fr.to_gregorian(7, 9, 30), (1799, 6, 18)) def test_french_republican_months(self): self.assertEqual(fr.MOIS[0], "Vendémiaire") self.assertEqual(fr.MOIS[1], "Brumaire") self.assertEqual(fr.MOIS[2], 'Frimaire') self.assertEqual(fr.MOIS[3], 'Nivôse') self.assertEqual(fr.MOIS[4], 'Pluviôse') self.assertEqual(fr.MOIS[5], 'Ventôse') self.assertEqual(fr.MOIS[6], 'Germinal') self.assertEqual(fr.MOIS[7], 'Floréal') self.assertEqual(fr.MOIS[8], 'Prairial') self.assertEqual(fr.MOIS[9], 'Messidor') self.assertEqual(fr.MOIS[10], 'Thermidor') self.assertEqual(fr.MOIS[12], 'Sansculottides') self.assertEqual(fr.MOIS[11], "Fructidor") def test_french_republican_schematic_error(self): self.assertRaises(ValueError, fr.from_jd, self.jd, method=400) self.assertRaises(ValueError, fr.from_jd, self.j, method=-1) def test_french_republican_names(self): self.assertEqual(fr.day_name(1, 1), "Raisin") self.assertEqual(fr.day_name(2, 1), "Pomme") self.assertEqual(fr.day_name(4, 18), "Pierre à chaux") self.assertEqual(fr.day_name(12, 15), "Truite") self.assertEqual(fr.day_name(13, 1), "La Fête de la Vertu") if __name__ == '__main__': unittest.main() convertdate-2.1.3/tests/test_gregorian.py000066400000000000000000000100741334033033100205560ustar00rootroot00000000000000# -*- coding: utf-8 -*- import unittest import time from convertdate import gregorian from convertdate import julian class TestGregorian(unittest.TestCase): def reflexive(self, from_func, to_func): for jd in self.jdcs: self.assertEqual(jd + 0.5, to_func(*from_func(jd + 0.5))) def setUp(self): self.tm = time.localtime() self.gregoriandate = (self.tm[0], self.tm[1], self.tm[2]) self.jd = gregorian.to_jd(self.gregoriandate[0], self.gregoriandate[1], self.gregoriandate[2]) self.c_greg = (1492, 10, 21) self.c = gregorian.to_jd(*self.c_greg) self.jdcs = range(2159677, 2488395, 2000) def test_gregorian(self): assert gregorian.to_jd(*self.gregoriandate) == self.jd assert gregorian.to_jd2(*self.gregoriandate) == self.jd self.assertEqual(self.c, 2266295.5) assert gregorian.to_jd(2000, 1, 1) == 2451544.5 assert gregorian.to_jd2(2000, 1, 1) == 2451544.5 self.reflexive(gregorian.from_jd, gregorian.to_jd) def test_gregorian_proleptic(self): self.assertEqual(gregorian.to_jd(72, 6, 27), 1747535.5) assert gregorian.to_jd2(72, 6, 27) == 1747535.5 for y in range(int(gregorian.EPOCH), int(gregorian.EPOCH) - 10000, -250): assert gregorian.to_jd(*gregorian.from_jd(y)) == y - 0.5 assert gregorian.from_jd(gregorian.to_jd(-1, 3, 1)) == (-1, 3, 1) assert gregorian.from_jd(gregorian.to_jd(-100, 7, 1)) == (-100, 7, 1) assert gregorian.from_jd(gregorian.to_jd(-500, 12, 31)) == (-500, 12, 31) assert gregorian.from_jd(gregorian.to_jd(-1000, 1, 1)) == (-1000, 1, 1) def test_from_gregorian_20thc(self): self.assertEqual(gregorian.from_jd(2418934.0), (1910, 9, 19)) self.assertEqual(gregorian.from_jd(2433360.0), (1950, 3, 19)) self.assertEqual(gregorian.from_jd(2437970.0), (1962, 11, 1)) self.assertEqual(gregorian.from_jd(2447970.0), (1990, 3, 19)) self.assertEqual(gregorian.from_jd(2456967.5), (2014, 11, 6)) def test_to_gregorian(self): self.assertEqual(gregorian.to_jd(2014, 11, 5), 2456966.5) assert gregorian.to_jd(2012, 3, 1) == 1 + gregorian.to_jd(2012, 2, 29) assert gregorian.from_jd(gregorian.to_jd(2012, 2, 29) + 1) == (2012, 3, 1) assert gregorian.from_jd(gregorian.to_jd(2011, 2, 28) + 1) == (2011, 3, 1) assert gregorian.from_jd(gregorian.to_jd(2012, 3, 2) - 2) == (2012, 2, 29) assert gregorian.from_jd(gregorian.to_jd(2011, 3, 2) - 2) == (2011, 2, 28) def test_gregorian_1_ma(self): assert gregorian.to_jd(*self.c_greg) == 2266295.5 def test_gregorian_2_ma(self): assert gregorian.to_jd2(*self.c_greg) == 2266295.5 def test_gregorian_julian_dif_proleptic(self): self.assertEqual(julian.to_jd(1500, 5, 10), gregorian.to_jd(1500, 5, 20)) assert julian.to_jd(1300, 5, 10) == gregorian.to_jd(1300, 5, 18) assert julian.to_jd(1000, 5, 10) == gregorian.to_jd(1000, 5, 16) assert julian.to_jd(900, 5, 10) == gregorian.to_jd(900, 5, 15) assert julian.to_jd(300, 5, 10) == gregorian.to_jd(300, 5, 11) assert julian.to_jd(200, 5, 10) == gregorian.to_jd(200, 5, 10) assert julian.to_jd(100, 5, 10) == gregorian.to_jd(100, 5, 9) assert julian.to_jd(-1, 5, 10) == gregorian.to_jd(-1, 5, 8) def test_year_zero(self): assert gregorian.to_jd(1, 1, 1) == 1.0 + gregorian.to_jd(0, 12, 31) assert julian.to_jd(1, 1, 1) == 1.0 + julian.to_jd(0, 12, 31) assert julian.from_jd(julian.to_jd(1, 1, 1) - 1) == (0, 12, 31) self.assertEqual(gregorian.from_jd(gregorian.to_jd(1, 1, 1) - 1), (0, 12, 31)) def test_legal_date(self): self.assertRaises(ValueError, gregorian.to_jd, 1900, 2, 29) self.assertRaises(ValueError, gregorian.to_jd, 2014, 2, 29) self.assertRaises(ValueError, gregorian.to_jd, 2014, 3, 32) self.assertRaises(ValueError, gregorian.to_jd, 2014, 4, 31) self.assertRaises(ValueError, gregorian.to_jd, 2014, 5, -1) if __name__ == '__main__': unittest.main() convertdate-2.1.3/tests/test_holidays.py000066400000000000000000000154231334033033100204200ustar00rootroot00000000000000import unittest from datetime import datetime from convertdate import holidays class TestHolidays(unittest.TestCase): def setUp(self): self.h = holidays.Holidays(2015) def test_nth_day_of_month(self): assert holidays.nth_day_of_month(4, 2, 4, 2014) == (2014, 4, 23) self.assertRaises(IndexError, holidays.nth_day_of_month, 5, 3, 4, 2014) self.assertRaises(IndexError, holidays.nth_day_of_month, 6, 2, 4, 2014) self.assertRaises(IndexError, holidays.nth_day_of_month, 1, 7, 4, 2014) assert holidays.nth_day_of_month(4, 3, 11, 2014) == (2014, 11, 27) assert holidays.nth_day_of_month(0, 3, 11, 2014) == (2014, 11, 27) def test_holidays(self): h = holidays.Holidays(2014) self.assertEqual(h.christmas, (2014, 12, 25)) assert h.thanksgiving == (2014, 11, 27) assert h.columbus_day == (2014, 10, 13) assert h.independence_day == (2014, 7, 4) assert self.h.christmas == (2015, 12, 25) assert self.h.christmas_eve == (2015, 12, 24) assert self.h.new_years == (2015, 1, 1) assert self.h.new_years_eve == (2015, 12, 31) assert self.h.valentines_day == (2015, 2, 14) assert self.h.halloween == (2015, 10, 31) assert self.h.mothers_day == (2015, 5, 10) self.assertEqual(self.h.fathers_day, (2015, 6, 21)) def test_class(self): H = holidays.Holidays() assert H.year == datetime.now().year assert str(self.h) == 'Holidays(2015)' H.set_year(2010) assert H.year == 2010 def test_events(self): assert holidays.new_years(2013) == (2013, 1, 1) assert holidays.martin_luther_king_day(2015) == (2015, 1, 19) assert holidays.lincolns_birthday(2015) == (2015, 2, 12) assert holidays.valentines_day(2015) == (2015, 2, 14) assert holidays.washingtons_birthday(2015) == (2015, 2, 22) assert holidays.presidents_day(2015) == (2015, 2, 16) assert holidays.pulaski_day(2015) == (2015, 3, 2) assert self.h.pulaski_day == (2015, 3, 2) assert holidays.may_day(2015) == (2015, 5, 1) assert holidays.columbus_day(2015, 'canada') == (2015, 10, 12) assert holidays.independence_day(2015) == (2015, 7, 4) assert holidays.independence_day(2015, True) == (2015, 7, 3) def test_thanksgiving(self): assert holidays.thanksgiving(2013) == (2013, 11, 28) assert holidays.thanksgiving(1939) == (1939, 11, 23) self.assertEqual(holidays.thanksgiving(1941), (1941, 11, 20)) assert self.h.thanksgiving == (2015, 11, 26) assert holidays.thanksgiving(2015, 'canada') == (2015, 10, 12) def test_easter(self): easters = [ (1994, 4, 3), (1995, 4, 16), (1996, 4, 7), (1997, 3, 30), (1998, 4, 12), (1999, 4, 4), (2000, 4, 23), (2001, 4, 15), (2002, 3, 31), (2003, 4, 20), (2004, 4, 11), (2005, 3, 27), (2006, 4, 16), (2007, 4, 8), (2008, 3, 23), (2009, 4, 12), (2010, 4, 4), (2011, 4, 24), (2012, 4, 8), (2013, 3, 31), (2014, 4, 20), (2015, 4, 5), (2016, 3, 27), (2017, 4, 16), (2018, 4, 1), (2019, 4, 21), (2020, 4, 12), (2021, 4, 4), (2022, 4, 17), (2023, 4, 9), (2024, 3, 31), (2025, 4, 20), (2026, 4, 5), (2027, 3, 28), (2028, 4, 16), (2029, 4, 1), (2030, 4, 21), (2031, 4, 13), (2032, 3, 28), (2033, 4, 17), (2034, 4, 9) ] for y, m, d in easters: self.assertEqual(holidays.easter(y), (y, m, d)) self.assertEqual(self.h.easter, (2015, 4, 5)) def test_jewish_holidays(self): # http://www.chabad.org/holidays/passover/pesach_cdo/aid/671901/jewish/When-is-Passover-in-2013-2014-2015-2016-and-2017.htm # the date here is the start of the holiday, so the eve=1 option is used passovers = [ (2013, 3, 25), (2014, 4, 14), (2015, 4, 3), (2016, 4, 22), (2017, 4, 10) ] for y, m, d in passovers: self.assertEqual(holidays.passover(y, eve=1), (y, m, d)) rosh_hashanahs = [ (2014, 9, 24), (2015, 9, 13), (2016, 10, 2), (2017, 9, 20), ] for y, m, d in rosh_hashanahs: self.assertEqual(holidays.rosh_hashanah(y, eve=1), (y, m, d)) self.assertEqual(holidays.hanukkah(2015, True), (2015, 12, 6)) self.assertEqual(holidays.hanukkah(2015), (2015, 12, 7)) self.assertEqual(holidays.yom_kippur(2015), (2015, 9, 23)) self.assertEqual(holidays.yom_kippur(2015, True), (2015, 9, 22)) sukkots = [ (2016, 10, 17), (2015, 9, 28), ] for y, m, d in sukkots: self.assertEqual(holidays.sukkot(y, eve=0), (y, m, d)) shavuots = [ (2016, 6, 12), (2015, 5, 24) ] for y, m, d in shavuots: self.assertEqual(holidays.shavuot(y, eve=0), (y, m, d)) purims = [ (2017, 3, 12), (2016, 3, 24) ] for y, m, d in purims: self.assertEqual(holidays.purim(y, eve=0), (y, m, d)) assert self.h.hanukkah == (2015, 12, 7) assert self.h.rosh_hashanah == (2015, 9, 14) assert self.h.yom_kippur == (2015, 9, 23) assert self.h.passover == (2015, 4, 4) def test_mexican_holidays(self): self.assertEqual(holidays.natalicio_benito_juarez(2015, False), (2015, 3, 21)) self.assertEqual(holidays.natalicio_benito_juarez(2015), (2015, 3, 16)) assert self.h.dia_constitucion == (2015, 2, 2) assert self.h.natalicio_benito_juarez == (2015, 3, 16) assert self.h.dia_independencia == (2015, 9, 16) assert self.h.dia_revolucion == (2015, 11, 16) def test_usa_holidays(self): assert self.h.independence_day == (2015, 7, 3) assert self.h.flag_day == (2015, 6, 14) assert self.h.election_day == (2015, 11, 3) assert self.h.presidents_day == (2015, 2, 16) assert self.h.washingtons_birthday == (2015, 2, 22) assert self.h.lincolns_birthday == (2015, 2, 12) assert self.h.memorial_day == (2015, 5, 25) assert self.h.labor_day == (2015, 9, 7) assert self.h.columbus_day == (2015, 10, 12) assert self.h.veterans_day == (2015, 11, 11) assert self.h.martin_luther_king_day == (2015, 1, 19) if __name__ == '__main__': unittest.main() convertdate-2.1.3/tests/test_mayan.py000066400000000000000000000063671334033033100177200ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals import unittest import time from convertdate import gregorian from convertdate import mayan class TestMayan(unittest.TestCase): def setUp(self): self.tm = time.localtime() self.gregoriandate = (self.tm[0], self.tm[1], self.tm[2]) self.c_greg = (1492, 10, 21) self.c = gregorian.to_jd(*self.c_greg) self.jd = gregorian.to_jd(self.gregoriandate[0], self.gregoriandate[1], self.gregoriandate[2]) self.jdcs = range(2159677, 2488395, 2000) def reflexive(self, from_func, to_func): for jd in self.jdcs: self.assertEqual(jd + 0.5, to_func(*from_func(jd + 0.5))) def test_mayan_reflexive(self): assert self.jd == mayan.to_jd(*mayan.from_jd(self.jd)) self.reflexive(mayan.from_jd, mayan.to_jd) def test_mayan_count(self): assert mayan.to_jd(13, 0, 0, 0, 0) == 2456282.5 assert mayan.from_gregorian(2012, 12, 21) == (13, 0, 0, 0, 0) assert mayan.to_gregorian(13, 0, 0, 0, 0) == (2012, 12, 21) assert mayan.from_jd(self.c) == (11, 13, 12, 4, 13) def test_mayan_haab(self): # haab assert mayan.HAAB_MONTHS[2] == 'Zip' assert mayan.HAAB_MONTHS.index("Xul") == 5 assert mayan.to_haab(self.c) == (16, "Sotz'") assert mayan.to_haab(2456282.5) == (3, "K'ank'in") def test_mayan_tzolkin(self): # tzolkin assert mayan.TZOLKIN_NAMES[0] == "Imix'" assert mayan.to_tzolkin(self.c) == (12, "B'en") assert mayan.to_tzolkin(2456282.5) == (4, 'Ajaw') assert mayan.to_tzolkin(2456850.5) == (13, 'Lamat') def test_mayan_convenience(self): self.assertEqual(mayan.lc_to_haab(0, 0, 0, 0, 0), (8, "Kumk'u")) assert mayan.lc_to_tzolkin(0, 0, 0, 0, 0) == (4, "Ajaw") assert mayan.lc_to_tzolkin(9, 16, 12, 5, 17) == (6, "Kab'an") assert mayan.lc_to_haab(9, 16, 12, 5, 17) == (10, "Mol") assert mayan.lc_to_haab_tzolkin(9, 16, 12, 5, 17) == "6 Kab'an 10 Mol" assert mayan.translate_haab("Wayeb'") == 'Nameless' def test_mayan_predictions(self): assert mayan.next_haab("Sotz'", self.c) == 2266280.5 for h in mayan.HAAB_MONTHS: assert mayan.to_haab(mayan.next_haab(h, self.c)) == (1, h) assert mayan.next_tzolkin_haab((13, "Ajaw"), (3, "Kumk'u"), 2456849.5) == 2463662.5 def test_mayan_monthcalendar(self): calendar = mayan.haab_monthcalendar(13, 0, 2, 11, 13) row = calendar[0] square = row[-1] assert isinstance(row, list) assert isinstance(square, tuple) assert row[7][0] == 1 assert mayan.to_jd(*calendar[-1][-1][-1]) == 19 + mayan.to_jd(13, 0, 2, 11, 13) self.assertEqual(square, (6, (13, "Etz'nab'"), (13, 0, 2, 11, 18))) def test_mayan_generators(self): lcg = mayan.longcount_generator(13, 0, 2, 11, 13) assert next(lcg) == (13, 0, 2, 11, 13) assert next(lcg) == (13, 0, 2, 11, 14) assert next(lcg) == (13, 0, 2, 11, 15) tzg = mayan.tzolkin_generator(9, "Ix") self.assertEqual(next(tzg), (9, "Ix")) assert next(tzg) == (10, "Men") assert next(tzg) == (11, "K'ib'") if __name__ == '__main__': unittest.main() convertdate-2.1.3/tests/test_positivist.py000066400000000000000000000103661334033033100210220ustar00rootroot00000000000000#!/usr/bin/env python # -*- coding: utf-8 -*- import unittest from convertdate.positivist import ( EPOCH, from_jd, to_jd, from_gregorian, to_gregorian, legal_date, dayname, festival ) from convertdate.data import positivist as data class TestGregorian(unittest.TestCase): def setUp(self): pass def test_epoch(self): self.assertEqual(to_jd(1, 1, 1), EPOCH) self.assertEqual(to_jd(1, 1, 2), EPOCH + 1) self.assertEqual(to_jd(2, 1, 1), EPOCH + 365.0) self.assertEqual(from_jd(EPOCH), (1, 1, 1)) def test_to_gregorian(self): self.assertEqual(to_gregorian(228, 13, 25), (2016, 12, 26)) self.assertEqual(to_gregorian(228, 13, 25), (2016, 12, 26)) def test_legaldate(self): self.assertTrue(legal_date(1, 1, 1)) with self.assertRaises(ValueError): legal_date(0, 1, 1) with self.assertRaises(ValueError): legal_date(1, -1, 1) with self.assertRaises(ValueError): legal_date(1, 14, 3) with self.assertRaises(ValueError): legal_date(1, 16, 3) def test_from_jd(self): self.assertTrue(legal_date(*from_jd(2375479.5))) assert legal_date(*from_jd(2376479.5)) assert legal_date(*from_jd(2378479.5)) assert legal_date(*from_jd(2379479.5)) with self.assertRaises(ValueError): from_jd(EPOCH - 0.5) def test_reflexive_jd(self): self.assertEqual(from_jd(to_jd(1, 1, 1)), (1, 1, 1)) self.assertEqual(from_jd(to_jd(4, 1, 1)), (4, 1, 1)) self.assertEqual(from_jd(to_jd(4, 14, 1)), (4, 14, 1)) self.assertEqual(from_jd(to_jd(4, 14, 2)), (4, 14, 2)) self.assertEqual(from_jd(to_jd(10, 1, 1)), (10, 1, 1)) self.assertEqual(from_jd(to_jd(12, 1, 1)), (12, 1, 1)) self.assertEqual(from_jd(to_jd(13, 1, 1)), (13, 1, 1)) self.assertEqual(from_jd(to_jd(13, 1, 2)), (13, 1, 2)) self.assertEqual(from_jd(to_jd(13, 1, 3)), (13, 1, 3)) self.assertEqual(from_jd(to_jd(13, 1, 5)), (13, 1, 5)) self.assertEqual(from_jd(to_jd(13, 1, 7)), (13, 1, 7)) self.assertEqual(from_jd(to_jd(13, 1, 14)), (13, 1, 14)) self.assertEqual(from_jd(to_jd(13, 1, 28)), (13, 1, 28)) self.assertEqual(from_jd(to_jd(13, 2, 28)), (13, 2, 28)) self.assertEqual(from_jd(to_jd(13, 6, 1)), (13, 6, 1)) self.assertEqual(from_jd(to_jd(14, 1, 1)), (14, 1, 1)) self.assertEqual(from_jd(to_jd(16, 1, 1)), (16, 1, 1)) self.assertEqual(from_jd(to_jd(50, 1, 1)), (50, 1, 1)) self.assertEqual(from_jd(to_jd(99, 1, 1)), (99, 1, 1)) self.assertEqual(from_jd(to_jd(100, 1, 1)), (100, 1, 1)) self.assertEqual(from_jd(to_jd(100, 13, 25)), (100, 13, 25)) self.assertEqual(from_jd(to_jd(120, 13, 25)), (120, 13, 25)) self.assertEqual(from_jd(to_jd(50, 13, 25)), (50, 13, 25)) self.assertEqual(from_jd(to_jd(200, 1, 5)), (200, 1, 5)) self.assertEqual(from_jd(to_jd(250, 14, 1)), (250, 14, 1)) def test_reflexive_jd2(self): assert len(from_jd(2375479.5)) == 3 self.assertEqual(to_jd(*from_jd(2375479.5)), 2375479.5) self.assertEqual(to_jd(*from_jd(2376479.5)), 2376479.5) self.assertEqual(to_jd(*from_jd(2378479.5)), 2378479.5) self.assertEqual(to_jd(*from_jd(2379479.5)), 2379479.5) def test_reflexive_gregorian(self): self.assertEqual(from_gregorian(*to_gregorian(100, 13, 25)), (100, 13, 25)) self.assertEqual(from_gregorian(*to_gregorian(120, 13, 25)), (120, 13, 25)) self.assertEqual(from_gregorian(*to_gregorian(50, 13, 25)), (50, 13, 25)) self.assertEqual(from_gregorian(*to_gregorian(200, 1, 5)), (200, 1, 5)) self.assertEqual(from_gregorian(*to_gregorian(250, 14, 1)), (250, 14, 1)) def test_named_day(self): self.assertEqual(dayname(228, 13, 25), ('Bichat', "Félix Vicq-d'Azyr")) self.assertEqual(dayname(228, 1, 1), ('Moses', "Cadmus")) self.assertEqual(dayname(227, 1, 1), ('Moses', "Prometheus")) self.assertEqual(dayname(1, 1, 1), ('Moses', "Prometheus")) def test_festival(self): self.assertIsNone(festival(1, 2)) self.assertEqual(festival(1, 1), data.festivals.get((1, 1))) if __name__ == '__main__': unittest.main() convertdate-2.1.3/tests/tests.py000066400000000000000000000211521334033033100167030ustar00rootroot00000000000000# -*- coding: utf-8 -*- import unittest import time from datetime import datetime import pytz from convertdate import utils from convertdate import bahai from convertdate import coptic from convertdate import dublin from convertdate import gregorian from convertdate import hebrew from convertdate import islamic from convertdate import indian_civil from convertdate import iso from convertdate import julian from convertdate import julianday from convertdate import persian from convertdate import ordinal class CalTestCase(unittest.TestCase): def setUp(self): self.tm = time.localtime() self.gregoriandate = (self.tm[0], self.tm[1], self.tm[2]) self.jd = gregorian.to_jd(self.gregoriandate[0], self.gregoriandate[1], self.gregoriandate[2]) self.c_greg = (1492, 10, 21) self.c = gregorian.to_jd(*self.c_greg) self.x = gregorian.to_jd(2016, 2, 29) self.jdcs = range(2159677, 2488395, 2000) def test_utils(self): self.assertEqual(utils.amod(100, 4), 4) self.assertEqual(utils.ceil(1.2), 2) self.assertEqual(utils.jwday(self.jd), self.tm[6]) def reflexive(self, from_func, to_func): for jd in self.jdcs: self.assertEqual(jd + 0.5, to_func(*from_func(jd + 0.5))) def test_julian_legal_date(self): try: julian.to_jd(1900, 2, 29) except ValueError: self.fail('Unexpected ValueError: "julian.to_jd(1900, 2, 29)"') self.assertRaises(ValueError, julian.to_jd, 2014, 2, 29) self.assertRaises(ValueError, julian.to_jd, 2014, 3, 32) self.assertRaises(ValueError, julian.to_jd, 2014, 4, 31) self.assertRaises(ValueError, julian.to_jd, 2014, 5, -1) def test_hebrew(self): self.assertEqual(self.jd, hebrew.to_jd(*hebrew.from_jd(self.jd))) self.reflexive(hebrew.from_jd, hebrew.to_jd) def test_islamic(self): self.assertEqual(self.jd, islamic.to_jd(*islamic.from_jd(self.jd))) self.reflexive(islamic.from_jd, islamic.to_jd) def test_persian(self): self.assertEqual(self.jd, persian.to_jd(*persian.from_jd(self.jd))) self.assertEqual(persian.leap(-101), False) self.reflexive(persian.from_jd, persian.to_jd) def test_indian_civil(self): self.assertEqual(self.jd, indian_civil.to_jd(*indian_civil.from_jd(self.jd))) self.reflexive(indian_civil.from_jd, indian_civil.to_jd) def test_iso(self): self.assertEqual(iso.from_gregorian(2005, 1, 1), (2004, 53, 6)) self.assertEqual(iso.to_gregorian(2004, 53, 6), (2005, 1, 1)) self.assertEqual(self.jd, iso.to_jd(*iso.from_jd(self.jd))) self.reflexive(iso.from_jd, iso.to_jd) def test_ordinal(self): self.assertEqual(ordinal.from_gregorian(2013, 1, 1), (2013, 1)) self.assertEqual(ordinal.from_gregorian(2013, 2, 1), (2013, 32)) self.assertEqual(ordinal.from_gregorian(2013, 3, 1), (2013, 60)) self.assertEqual(ordinal.from_gregorian(2013, 4, 15), (2013, 105)) self.reflexive(ordinal.from_jd, ordinal.to_jd) def test_ordinal_to_gregorian(self): self.assertEqual(ordinal.to_gregorian(2013, 1), (2013, 1, 1)) self.assertEqual(ordinal.to_gregorian(2013, 105), (2013, 4, 15)) self.assertEqual(ordinal.to_gregorian(2013, 32), (2013, 2, 1)) self.assertEqual(ordinal.to_gregorian(2012, 1), (2012, 1, 1)) self.assertEqual(ordinal.to_gregorian(2012, 31), (2012, 1, 31)) self.assertEqual(ordinal.to_gregorian(2012, 32), (2012, 2, 1)) self.assertEqual(ordinal.to_gregorian(2012, 52), (2012, 2, 21)) self.assertEqual(ordinal.to_gregorian(2012, 59), (2012, 2, 28)) self.assertEqual(ordinal.to_gregorian(2012, 60), (2012, 2, 29)) self.assertEqual(ordinal.to_gregorian(2012, 61), (2012, 3, 1)) def test_from_julian(self): self.assertEqual(self.jd, julian.to_jd(*julian.from_jd(self.jd))) self.assertEqual(julian.from_jd(self.c), (1492, 10, 12)) self.assertEqual(julian.from_jd(2400000.5), (1858, 11, 5)) self.assertEqual(julian.from_jd(2399830.5), (1858, 5, 19)) def test_julian_inverse(self): self.reflexive(julian.from_jd, julian.to_jd) def test_to_julian(self): self.assertEqual(julian.to_jd(1858, 11, 5), 2400000.5) self.assertEqual(julian.to_jd(1492, 10, 12), self.c) def test_bahai(self): self.reflexive(bahai.from_jd, bahai.to_jd) self.assertEqual(bahai.from_gregorian(1844, 3, 21), (1, 1, 1)) self.assertEqual(bahai.to_gregorian(1, 1, 1), (1844, 3, 21)) self.assertEqual(bahai.month_length(1, 3), 19) self.assertEqual(bahai.month_length(1, 1), 19) self.assertEqual(bahai.month_length(4, 19), 5) self.assertEqual(bahai.month_length(5, 19), 4) self.assertEqual(self.jd, bahai.to_jd(*bahai.from_jd(self.jd))) def test_coptic(self): self.assertEqual(coptic.to_jd(1000, 1, 1), 2189914.5) self.assertEqual(coptic.to_jd(1666, 6, 1), 2433320.5) self.assertEqual(coptic.to_jd(1, 1, 1), 1825029.5) self.assertEqual(coptic.from_jd(2437970.5), (1679, 2, 23)) self.assertEqual(coptic.to_jd(1259, 13, 6), 2284878.5) self.assertEqual(coptic.from_jd(2284878.5), (1259, 13, 6)) self.reflexive(coptic.from_jd, coptic.to_jd) self.assertEqual(coptic.from_gregorian(2017, 1, 7), (1733, 4, 29)) self.assertEqual(coptic.to_gregorian(1727, 11, 11), (2011, 7, 18)) def test_dublin_dc(self): self.assertEqual(dublin.from_gregorian(1900, 1, 1), 0.5) self.assertEqual(dublin.to_gregorian(1), (1900, 1, 1)) self.assertEqual(dublin.to_jd(0), 2415020.0) self.assertEqual( dublin.to_jd(dublin.from_jd(self.c)), gregorian.to_jd(*dublin.to_gregorian(dublin.from_gregorian(*self.c_greg))) ) self.assertEqual(dublin.to_gregorian(dublin.from_jd(1737936)), gregorian.from_jd(1737936)) self.assertEqual(dublin.to_julian(dublin.from_jd(1737936)), julian.from_jd(1737936)) def test_julian_day(self): self.assertEqual(julianday.from_gregorian(*self.c_greg), self.c) self.assertEqual(julianday.to_datetime(self.c), datetime(1492, 10, 21, tzinfo=pytz.utc)) self.assertEqual(julianday.to_datetime(self.x), datetime(2016, 2, 29, tzinfo=pytz.utc)) self.assertEqual(julianday.to_datetime(self.c + 0.25), datetime(1492, 10, 21, 6, tzinfo=pytz.utc)) self.assertEqual(julianday.to_datetime(self.x + 0.525), datetime(2016, 2, 29, 12, 36, tzinfo=pytz.utc)) dt = datetime(2014, 11, 8, 3, 37, tzinfo=pytz.utc) self.assertEqual(julianday.from_datetime(dt), 2456969.65069) self.assertEqual(julianday.to_datetime(self.x + 0.525), datetime(2016, 2, 29, 12, 36, tzinfo=pytz.utc)) def test_month_length_indian_civil(self): self.assertEqual(indian_civil.month_length(1922, 1), 31) self.assertEqual(indian_civil.month_length(1923, 1), 30) def test_month_length_julian(self): self.assertEqual(julian.month_length(1582, 10), 31) self.assertEqual(julian.month_length(1977, 2), 28) self.assertEqual(julian.month_length(1900, 2), 29) self.assertEqual(julian.month_length(1904, 2), 29) def test_month_length_islamic(self): self.assertEqual(islamic.month_length(1436, 1), 30) self.assertEqual(islamic.month_length(1436, 2), 29) self.assertEqual(islamic.month_length(1436, 12), 30) def test_month_length_persian(self): self.assertEqual(persian.month_length(1354, 12), 30) self.assertEqual(persian.month_length(1355, 12), 29) def test_monthcalendar_indian_civil(self): self.assertEqual(indian_civil.monthcalendar(1936, 8).pop(0).pop(4), 1) self.assertEqual(indian_civil.monthcalendar(1927, 2).pop(0).pop(4), 1) self.assertEqual(indian_civil.monthcalendar(1922, 1).pop().pop(4), 31) def test_monthcalendar_julian(self): self.assertEqual(julian.monthcalendar(1582, 10).pop(0).pop(1), 1) self.assertEqual(julian.monthcalendar(1582, 10).pop().pop(3), 31) def test_monthcalendar_islamic(self): self.assertEqual(islamic.monthcalendar(1436, 10).pop(0).pop(6), 1) self.assertEqual(islamic.monthcalendar(1436, 11).pop().pop(1), 30) def test_monthcalendar_persian(self): self.assertEqual(persian.monthcalendar(1393, 8).pop(0).pop(4), 1) self.assertEqual(persian.monthcalendar(1393, 8).pop().pop(0), 25) def test_monthcalendar_hebrew(self): self.assertEqual(hebrew.monthcalendar(5775, 7).pop(0).pop(4), 1) self.assertEqual(hebrew.monthcalendar(5775, 7).pop().pop(0), 25) if __name__ == '__main__': unittest.main() convertdate-2.1.3/tox.ini000066400000000000000000000006461334033033100153450ustar00rootroot00000000000000# This file is part of convertdate. # http://github.com/fitnr/convertdate # Licensed under the GPL-v3.0 license: # http://opensource.org/licenses/MIT # Copyright (c) 2016, fitnr [tox] envlist = py27,pypy,py34,py35,py36,pep8 [testenv] deps = coverage commands = coverage run --source convertdate setup.py -q test [testenv:pep8] deps = flake8 commands = flake8 --ignore=E501 convertdate/ tests/