root/lu/LUDate.lua

Revision 814 (checked in by rsz, 3 years ago)

cleanup

Line 
1 --------------------------------------------------------------------------------
2 -- Title:               LUDate.lua
3 -- Description:         Like a square peg in a round hole
4 -- Author:              Raphaël Szwarc http://alt.textdrive.com/lua/
5 -- Creation Date:       February 1, 2005
6 -- Legal:               Copyright (C) 2005 Raphaël Szwarc
7 --------------------------------------------------------------------------------
8
9 -- import dependencies
10 local LUObject = require( "LUObject" )
11 local LUString = require( "LUString" )
12 local math = require( "math" )
13 local os = require( "os" )
14
15 -- constant(s)
16 local Second = 1
17 local Minute = 60 * Second
18 local Hour = 60 * Minute
19 local Day = 24 * Hour
20 local Week = 7 * Day
21 local Month = 31 * Day
22 local Year = 365 * Day
23 local Durations = { Y = Year, M = Month, W = Week, D = Day, h = Hour, m = Minute, s = Second }
24
25 -- define the class
26 local super = LUObject
27 local self = super()
28
29 -- initialization method
30 function self:init( aTime )
31         self = super.init( self )
32
33         self._time = aTime
34        
35         return self
36 end
37
38 -- method to access this date time
39 function self:time()
40         if self._time == nil then
41                 self._time = os.time()
42         end
43        
44         return self._time
45 end
46
47 -- method to access this date's date table
48 function self:date()
49         if self._date == nil then
50                 self._date = os.date( "*t", self:time() )
51         end
52
53         return self._date
54 end
55
56 -- method to compare the given object with this object
57 function self:compare( anObject )
58         return self:time() < anObject:time()
59 end
60
61  -- method for equality
62 function self:equals( anObject )
63         if self:isKindOf( anObject ) == true then
64                 if self:time() == anObject:time() then
65                         return true
66                 end
67         end
68
69         return false
70 end
71
72 -- method for hashing
73 function self:hashCode()
74         return self:time()
75 end
76
77 -- method to access this date year
78 function self:year()
79         return self:date()[ "year" ]
80 end
81
82 -- method to access this date month
83 function self:month()
84         return self:date()[ "month" ]
85 end
86
87 -- method to access this date week
88 function self:week()
89         return tonumber( self:toString( "%U" ) )
90 end
91
92 -- method to access this month number of weeks
93 function self:weeksInMonth()
94         return self:monthEndDate():week() - self:monthDate():week() + 1
95 end
96
97 -- method to access this date day
98 function self:day()
99         return self:date()[ "day" ]
100 end
101
102 -- method to access this date day of year
103 function self:dayOfYear()
104         return self:date()[ "yday" ]
105 end
106
107 -- method to access this date day of week
108 function self:dayOfWeek()
109         return self:date()[ "wday" ]
110 end
111
112 -- method to access this date hour
113 function self:hour()
114         return self:date()[ "hour" ]
115 end
116
117 -- method to access this date minute
118 function self:minute()
119         return self:date()[ "min" ]
120 end
121
122 -- method to access this date second
123 function self:second()
124         return self:date()[ "sec" ]
125 end
126
127 -- method to access this date day saving time
128 function self:isDST()
129         return self:date()[ "isdst" ]
130 end
131
132 -- method to access this date UTC time
133 function self:utc()
134         local anOffset = self:timeZoneOffset()
135        
136         if anOffset ~= nil then
137                 return self:time() - anOffset
138         end
139        
140         return self:time()
141 end
142
143 -- method to access this date UTC date
144 function self:utcDate()
145         return self:new( self:utc() )
146 end
147
148 -- method to access the day date
149 function self:dayDate()
150         local someValues = { year = self:year(), month = self:month(), day = self:day(), hour = 0, min = 0, sec = 0 }
151        
152         return self:dateWithValues( someValues )
153 end
154
155 -- method to access the week date
156 function self:weekDate()
157         local someValues = { year = self:year(), month = self:month(), day = self:day() - self:dayOfWeek() + 1, hour = 0, min = 0, sec = 0 }
158        
159         return self:dateWithValues( someValues )
160 end
161
162 -- method to access the month date
163 function self:monthDate()
164         local someValues = { year = self:year(), month = self:month(), day = 1, hour = 0, min = 0, sec = 0 }
165        
166         return self:dateWithValues( someValues )
167 end
168
169 -- method to access the year date
170 function self:yearDate()
171         local someValues = { year = self:year(), month = 1, day = 1, hour = 0, min = 0, sec = 0 }
172        
173         return self:dateWithValues( someValues )
174 end
175
176 -- method to access the end of the day date
177 function self:dayEndDate()
178         local someValues = { year = self:year(), month = self:month(), day = self:day(), hour = 23, min = 59, sec = 59 }
179        
180         return self:dateWithValues( someValues )
181 end
182
183 -- method to access the end of the week date
184 function self:weekEndDate()
185         local someValues = { year = self:year(), month = self:month(), day = self:day() + 7 - self:dayOfWeek(), hour = 23, min = 59, sec = 59 }
186        
187         return self:dateWithValues( someValues )
188 end
189
190 -- method to access the end of the month date
191 function self:monthEndDate()
192         local someValues = { year = self:year(), month = self:month() + 1, day = 0, hour = 23, min = 59, sec = 59 }
193        
194         return self:dateWithValues( someValues )
195 end
196
197 -- method to access the end of the year date
198 function self:yearEndDate()
199         local someValues = { year = self:year(), month = 12, day = 31, hour = 23, min = 59, sec = 59 }
200        
201         return self:dateWithValues( someValues )
202 end
203
204 -- method to add year, month, day, hour, minute and second to a date
205 function self:add( aYear, aMonth, aDay, anHour, aMinute, aSecond )
206         local aYear = self:year() + ( aYear or 0 )
207         local aMonth = self:month() + ( aMonth or 0 )
208         local aDay = self:day() + ( aDay or 0 )
209         local anHour = self:hour() + ( anHour or 0 )
210         local aMinute = self:minute() + ( aMinute or 0 )
211         local aSecond = self:second() + ( aSecond or 0 )
212         local someValues = { year = aYear, month = aMonth, day = aDay, hour = anHour, min = aMinute, sec = aSecond }
213        
214         return self:dateWithValues( someValues )
215 end
216
217 -- method to compute an approximate interval between two dates
218 function self:interval( aDate, aType )
219         local aDuration = Durations[ aType ] or Second
220         local anInterval = math.floor( math.abs( self:time() - aDate:time() ) / aDuration )
221        
222         if self > aDate then
223                 anInterval = -anInterval
224         end
225        
226         return anInterval
227 end
228
229 -- as per "Frequently Asked Questions about Calendars Version 2.7"
230 -- "2.16.1 Is there a formula for calculating the Julian day number?"
231 -- http://www.tondering.dk/claus/cal/node3.html#SECTION003161000000000000000
232
233 function self:julianDay()
234         local floor = math.floor
235         local a = floor( ( 14 - self:month() ) / 12 )
236         local y = self:year() + 4800 - a
237         local m = self:month() + ( 12 * a ) - 3
238         local aDay = self:day() + floor( ( ( 153 * m ) + 2 ) / 5 ) + ( 365 * y ) + floor( y / 4 ) - floor( y / 100 ) + floor( y / 400 ) - 32045
239        
240         return aDay
241 end
242
243 function self:dateWithJulianDay( aJulianDay )
244         local floor = math.floor
245         local a = aJulianDay + 32044
246         local b = floor( ( ( 4 * a ) + 3 ) / 146097 )
247         local c = a - floor( ( 146097 * b ) / 4 )
248         local d = floor( ( ( 4 * c ) + 3 ) / 1461 )
249         local e = c - floor( ( 1461 * d ) / 4 )
250         local m = floor( ( 5 * e + 2 ) / 153 )
251         local aDay = e - floor( ( 153 * m + 2 ) / 5 ) + 1
252         local aMonth = m + 3 - ( 12 * floor( m / 10 ) )
253         local aYear = ( 100 * b ) + d - 4800 + floor( m / 10 )
254         local someValues = { year = aYear, month = aMonth, day = aDay, hour = 0, min = 0, sec = 0 }
255
256         return self:dateWithValues( someValues )
257 end
258
259 -- method for string representation
260 function self:toString( aFormat )
261         if aFormat == nil then
262                 aFormat = "%Y-%m-%d %H:%M:%S"
263         end
264
265         return os.date( aFormat, self:time() )
266 end
267
268 -- method to create a date with the given values
269 function self:dateWithValues( someValues )
270         return self:new( os.time( someValues ) )
271 end
272
273 -- method to access the local time zone
274 function self:timeZone()
275         local aValue = os.date( "%Z", os.time() )
276        
277         if aValue == nil then
278                 aValue = "UTC"
279         end
280        
281         return aValue
282 end
283
284 -- method to access the local time zone offset
285 function self:timeZoneOffset()
286         local anOffset = os.date( "%z", os.time() )
287        
288         if anOffset ~= nil then
289                 local anHour, aMinute = anOffset:match( "(%d%d)(%d%d)" )
290                
291                 if anHour ~= nil and aMinute ~= nil then
292                         anHour = tonumber( anHour )
293                         aMinute = tonumber( aMinute )
294                        
295                         do
296                                 local aValue = ( anHour * 60 * 60 ) + ( aMinute * 60 )
297                                
298                                 if LUString:startsWith( anOffset, "-" ) == true then
299                                         aValue = 0 - aValue
300                                 end
301
302                                 return aValue
303                         end
304                 end
305         end
306        
307         return 0
308 end
309
310 return self
Note: See TracBrowser for help on using the browser.