-
Notifications
You must be signed in to change notification settings - Fork 3
/
republican-calendar.prg
136 lines (99 loc) · 3.23 KB
/
republican-calendar.prg
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
*!* RepublicanCalendar
*!* A CalendarCalc subclass for the historical French Republican Calendar.
*!* Locales are stored in republican.xml file.
*!* The extra 5 or 6 days at the end of a year are coded as belonging to the
*!* 13th month, although the Republican calendar only has 12 month
* install dependencies
IF _VFP.StartMode = 0
DO LOCFILE("calendar.prg")
ELSE
DO calendar.prg
ENDIF
* install itself
IF !SYS(16) $ SET("Procedure")
SET PROCEDURE TO (SYS(16)) ADDITIVE
ENDIF
* the Julian Day Number for 1 Vendémiaire 1 (first day of the calendar)
#DEFINE REPOCH 2375840
* the Julian Day Number for 10 Nivôse 14 (last day of the calendar)
#DEFINE RFINAL 2380687
#DEFINE SAFETHIS ASSERT !USED("This") AND VARTYPE(This) == "O"
DEFINE CLASS RepublicanCalendar AS CalendarCalc
MinYear = 1
MinMonth = 1
MinDay = 1
MaxYear = 14
MaxMonth = 4
MaxDay = 10
Historical = .T.
* IsLeapYear()
* returns .T. for leap years
FUNCTION IsLeapYear (Year AS Number) AS Boolean
SAFETHIS
ASSERT PCOUNT() = 0 OR VARTYPE(m.Year) == "N" ;
MESSAGE "Numeric parameter expected."
IF PCOUNT() = 0
m.Year = This.Year
ENDIF
RETURN INLIST(m.Year, 3, 7, 11)
ENDFUNC
* MonthName()
* gets the name of the month, for the current locale
* the final days of the year calendar are marked as the 13th month
FUNCTION MonthName (Month AS Number, Jour AS Number)
SAFETHIS
ASSERT PCOUNT() = 0 OR (VARTYPE(m.Month) == "N" AND (PCOUNT() = 1 OR VARTYPE(m.Jour) == "N")) ;
MESSAGE "Numeric parameters expected."
IF PCOUNT() = 0
m.Month = This.Month
ENDIF
IF m.Month = 13 AND PCOUNT() < 2
m.Jour = This.Day
ENDIF
IF ISNULL(This.Vocabulary)
This.SetVocabulary(LOCFILE("republican.xml"))
ENDIF
IF m.Month < 13
m.Name = This.GetLocale("month." + TRANSFORM(m.Month))
ELSE
m.Name = This.GetLocale("month.j." + TRANSFORM(m.Jour))
ENDIF
RETURN EVL(m.Name, .NULL.)
ENDFUNC
* calculation to transform a Julian Day Number into a Republican calendar date
* (called from FromJulian method)
* very simplified calculation, only valid for the legal period of the calendar
PROCEDURE _fromJulian (JulianDate AS Number)
SAFETHIS
LOCAL DaysInYear AS Number
LOCAL DaysLeft AS Number
IF BETWEEN(m.JulianDate, REPOCH, RFINAL)
This.Year = 1
m.DaysLeft = m.JulianDate - REPOCH + 1
m.DaysInYear = 365
DO WHILE m.DaysLeft > m.DaysInYear
m.DaysLeft = m.DaysLeft - m.DaysInYear
This.Year = This.Year + 1
m.DaysInYear = IIF(This.IsLeapYear(), 366, 365)
ENDDO
This.Month = INT((m.DaysLeft - 1)/ 30) + 1
This.Day = m.DaysLeft % 30
ELSE
STORE 0 TO This.Day, This.Month, This.Year
ENDIF
ENDPROC
* calculation to transform a Republican calendar date into a Julian Day Number
* (called from ToJulian method)
* very simplified calculation, only valid for the legal period of the calendar
FUNCTION _toJulian (CalYear AS Integer, CalMonth AS Integer, CalDay AS Integer)
LOCAL JulianDate AS Number
LOCAL YearsLeft AS Number
m.JulianDate = REPOCH + (m.CalMonth - 1) * 30 + (m.CalDay - 1)
m.YearsLeft = m.CalYear - 1
DO WHILE m.YearsLeft > 0
m.JulianDate = m.JulianDate + IIF(This.IsLeapYear(m.YearsLeft), 366, 365)
m.YearsLeft = m.YearsLeft - 1
ENDDO
RETURN m.JulianDate
ENDFUNC
ENDDEFINE