diff --git a/config.ld b/config.ld new file mode 100644 index 0000000..afa00c7 --- /dev/null +++ b/config.ld @@ -0,0 +1,7 @@ +project='LuaDate' +title='LuaDate; Date and time library' +description='Module for date and time manipulation, with timezone, string parsing, timespan support' +format='discount' +file='./date.lua' +dir='LDoc' +readme='readme.md' diff --git a/date.lua b/date.lua index f6855de..236ae0e 100644 --- a/date.lua +++ b/date.lua @@ -1,11 +1,10 @@ ---[[LuaDate version:2.1.0]]------------------------------- ---[[------------------------------------------------------ - Copyright (C) 2006, by Jas Latrix (jastejada@yahoo.com) - All Rights Deserved. - use this code at your own risk!. - keep out of reach of children. - Copyright (C) 2013 update to Lua 5.2 by Thijs Schreijer ---]]------------------------------------------------------ +--------------------------------------------------------------------------------------- +-- Module for date and time calculations +-- +-- @copyright Version 2.1.0, Copyright (C) 2006, by Jas Latrix (jastejada@yahoo.com), All Rights Deserved. Use this code at your own risk!. Keep out of reach of children. Copyright (C) 2013 update to Lua 5.2 by Thijs Schreijer +-- @name date +-- @class module + --[[ CONSTANTS ]]-- local HOURPERDAY = 24 local MINPERHOUR = 60 @@ -420,7 +419,9 @@ self.daynum, self.dayfrc = dn + floor(df/TICKSPERDAY), mod(df, TICKSPERDAY) return (dn >= DAYNUM_MIN and dn <= DAYNUM_MAX) and self or error("date beyond imposed limits:"..self) end - + --- Gets the date from a date object. + -- @return 3 return values; year, month, day + -- @example local y, m, d = MyDate:getdate() function dobj:getdate() local y, m, d = breakdaynum(self.daynum) return y, m+1, d end function dobj:gettime() return breakdayfrc(self.dayfrc) end diff --git a/doc/index_cleaned.html b/doc/index_cleaned.html new file mode 100644 index 0000000..fc42446 --- /dev/null +++ b/doc/index_cleaned.html @@ -0,0 +1,3991 @@ + + + + + + + + LuaDate v2 + + + + + +
+
+
+
+

LuaDate v2.1

+
+ +
+

Lua Date and Time module for Lua 5.x.

+
+ +
+
+

Jas Latrix

+
+
+ +
+ + + +
+ +
+
+ All Rights Deserved. Use at your own + risk!. Shake well before using. +
+
+
+
+
+ +
+

Table of Contents

+ +
+
1. Introduction
+ +
2. Limits
+ +
3. Local time + support
+ +
4. Parsable date + value
+ +
5. Parsable month + value
+ +
6. date
+ +
+
+
6.1. Function(s) of + date
+ +
6.2. Method(s) of + date
+
+
+ +
7. dateObject
+ +
+
+
7.1. How Date and Time are + stored in dateObject
+ +
7.2. Supported + MetaMethods
+ +
7.3. Method(s) of + dateObject
+
+
+ +
8. History
+ +
9. Acknowledgement
+
+
+ +
+
+
+
+

1. Introduction

+
+
+
LuaDate is a Lua module for date and time + calculation and retrieval using the Gregorian Date system. + +

To Load the module call local date = require"date" in + your script. Make sure Lua can find the source file date.lua. No global table date + will be created. Use the metamethod __call to construct + a dateObject see example below:

+
+local date = require "date"
+-- prints all FRIDAY the 13TH dates between year 2000 and 2010
+for i = 2000, 2010 do
+        -- year jan 1
+        x = date(i, 1, 1)
+        -- from january to december
+        for j = 1, 12 do
+                -- set date to 13, check if friday
+                if x:setmonth(j, 13):getweekday() == 6 then
+                        print(x:fmt("%A, %B %d %Y"))
+                end
+        end
+end
+
+--- OUTPUT ---
+--> Friday, October 13 2000
+--> Friday, April 13 2001
+--> Friday, July 13 2001
+--> Friday, September 13 2002
+--> Friday, December 13 2002
+--> Friday, June 13 2003
+--> Friday, February 13 2004
+--> Friday, August 13 2004
+--> Friday, May 13 2005
+--> Friday, January 13 2006
+--> Friday, October 13 2006
+--> Friday, April 13 2007
+--> Friday, July 13 2007
+--> Friday, June 13 2008
+--> Friday, February 13 2009
+--> Friday, March 13 2009
+--> Friday, November 13 2009
+--> Friday, August 13 2010
+
+
+ +
+
+
+
+

2. Limits

+
+
+
+ +
+
    +
  • This module does not recognize leap seconds.
  • + +
  • It assumes that a day has exactly 24*60*60 + seconds.
  • + +
  • The Lua number must be a double C data type
  • + +
  • This module supports dates that are greater than Mon + Jan 01 1000000 BCE 00:00:00 and less than Mon Jan + 01 1000001 00:00:00.
  • + +
  • see Local time support for local time + limts
  • +
+
+
+ +
+
+
+
+

3. Local time support

+
+
+
This module also supports local time. Local Time is; + +
+
+ Local = UTC + bias +
+
The bias is time zone offset plus the + daylight savings if in effect. The bias is + retrieve using the Lua function os.date and os.time. It assumes that the Lua function os.time returns the number of seconds + since the start time (called "epoch"). If the time value is outside + the allowable range of times, usually Jan 01 1970 + 00:00:00 to Jan 19 2038 03:14:07 the bias will + be retrieve using the equivalent year inside the allowable range. Two years are + considered to equivalent if they have the same leap year ness and starting weekday. + +

The function that needs local time support are date(true) (get the current UTC time), date(false) (get the current local + time), date(num_time), + dateObj:getbias(), + dateObject:fmt(str) (when str + has a '%Z' or '%z'),

+
+ +
+
+
+
+

4. Parsable date value

+
+
+
Parsable date value is a lua value that can be converted to a dateObject. This value must be num_time + or tbl_date or str_date or + bool_now argument describe in the date library __call method. +
+ +
+
+
+
+

5. Parsable month value

+
+
+
If a function needs a month value it must be a string or a number. If the + value is a string, it must be the name of the month + full or abbreviated. If the value is a number, that + number must be 1-12 (January-December). see table below + +
+ + +

Table 1. 

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
IndexAbbreviationFull Name
1JanJanuary
2FebFebruary
3MarMarch
4AprApril
5MayMay
6JunJune
7JulJuly
8AugAugust
9SepSeptember
10OctOctober
11NovNovember
12DecDecember
+
+

+ +

If the value does not represent month, that is equivalent to passing a nil + value.

+
+ +
+
+
+
+

6. date

+
+
+
The date module. + +
+
+
+
+

6.1. Function(s) of date

+
+
+
+ +
+
+
diff | epoch | + isleapyear 3
+
+
+ +
+
+
+
+

6.1.1. diff

+
+
+
Subtract the date + and time value of two dateObject and returns the + resulting dateObject. + +
+
+
Syntax
+ +
+
+date.diff(var_date1, var_date2)
+
+
+ +
Arguments
+ +
+
+
+
var_date1
+ +
Required. a dateObject or parsable date value
+ +
var_date2
+ +
Required. a dateObject or parsable date value
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
SuccessThe resulting dateObject
Failurenil.
+
+ +
Example
+ +
+
+-- get the days between two dates
+d = date.diff("Jan 7 1563", date(1563, 1, 2))
+assert(d:spandays()==5)
+
+
+
+
+
+ +
+
+
+
+

6.1.2. epoch

+
+
+
Returns dateObject whose date and time value is the Operating System + epoch. + +
+
+
Syntax
+ +
+
+date.epoch()
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
SuccessThe resulting dateObject
Failurenil.
+
+ +
Example
+ +
+
+assert(date.epoch()==date("jan 1 1970"))
+
+
+
+
+
+ +
+
+
+
+

6.1.3. isleapyear

+
+
+
Check if a number + or dateObject is a leapyear. + +
+
+
Syntax
+ +
+
+date.isleapyear(var_year)
+
+
+ +
Arguments
+ +
+
+
+
var_year
+ +
a number or dateObject or parsable date value
+
+
+
+ +
Returns
+ +
true if var_year leap year. false + if var_year not leap year.
+ +
Remarks
+ +
A leap year in the Gregorian calendar is defined as a year that is + evenly divisible by four, except if it is divisible by 100; however, years + that are divisible by 400 are leap years.
+ +
Example
+ +
+
+d = date(1776, 1, 1)
+assert(date.isleapyear(d))
+assert(date.isleapyear(d:getyear()))
+assert(date.isleapyear(1776))
+
+
+
+
+
+
+ +
+
+
+
+

6.2. Method(s) of date

+
+
+
+ +
+
+
__call 1
+
+
+ +
+
+
+
+

6.2.1. __call

+
+
+
Construct a + dateObject. It has 3 method of constructing a date + object. + +
+
    +
  • 3 or more arguments - int_year, var_month, + int_day, num_hour, num_min, num_sec, int_ticks
  • + +
  • 1 argument - num_time or + tbl_date or str_date or bool_now
  • + +
  • no argument - same as date(false)
  • +
+
This is a metamethod of date. Remember date:__call(...) is the same as date(...). + +
+
+
Syntax
+ +
+
+date(num_time)
+
+
+date(tbl_date)
+
+
+date(str_date)
+
+
+date(bool_now)
+
+
+date(int_year, var_month, int_day, [num_hour], [num_min], [num_sec], [int_ticks])
+
+
+ +
Arguments
+ +
+
+ +
+
+
num_time
+ +
Required number value. Represents + the number of seconds in Universal Coordinated Time between the + specified value and the System epoch.
+
+
+ +
+
+
tbl_date
+ +
+ Required table value. The + constructor will look for the value of this key: + +
+
    +
  • year - an integer, + the full year, for example, 1969. Required if month and day is + given
  • + +
  • month - a parsable month value. Required if + year and day is given
  • + +
  • day - an integer, + the day of month from 1 to 31. Required if year and month is + given
  • + +
  • hour - a number, + hours value, from 0 to 23, indicating the number of hours since + midnight. (default = 0)
  • + +
  • min - a number, + minutes value, from 0 to 59. (default = 0)
  • + +
  • sec - a number, + seconds value, from 0 to 59. (default = 0)
  • +
+
Time (hour or min or sec or + msec) must be supplied if date (year and month and day) is not + given, vice versa. +
+
+
+ +
+
+
str_date
+ +
+ Required string value. It must have + number/words representing date and/or time. Use commas and spaces + as delimiters. Strings enclosed by parenthesis is treated as a + comment and is ignored, these parentheses may be nested. The stated + day of the week is ignored whether its correct or not. A string + containing an invalid date is an error. For example, a string + containing two years or two months is an error. Time must be + supplied if date is not given, vice versa. + +

Time Format.  Hours, minutes, and seconds are + separated by colons, although all need not be specified. "10:", + "10:11", and "10:11:12" are all valid. If the 24-hour clock is + used, it is an error to specify "PM" for times later than 12 noon. + For example, "23:15 PM" is an error.

+ +

Time Zone Format.  First character is a sign "+" + (east of UTC) or "-" (west of UTC). Hours and minutes offset are + separated by colons:

+
+assert( date("Jul 27 2006 03:56:28 +2:00") == date(2006,07,27,1,56,28))
+
+ +

Another format is [sign][number] + If [number] is less than 24, it is + the offset in hours e.g. "-10" = -10 hours. Otherwise it is the + offset in houndred hours e.g. "+75" = "+115" = +1.25 hours.

+
+assert(date("Jul 27 2006 -75 ") == date(2006,07,27,1,15,0))
+assert(date("Jul 27 2006 -115") == date(2006,07,27,1,15,0))
+assert(date("Jul 27 2006 +10 ") == date(2006,07,26,14,0,0))
+assert(date("Jul 27 2006 +2  ") == date(2006,07,26,22,0,0))
+
+ +

Standard timezone GMT, UTC, EST, EDT, CST, CDT, MST, MDT, PST, + PDT are supported.

+
+assert(date("Jul 27 2006 GMT") == date(2006,07,27,0,0,0))
+assert(date("Jul 27 2006 UTC") == date(2006,07,27,0,0,0))
+assert(date("Jul 27 2006 EST") == date(2006,07,27,5,0,0))
+assert(date("Jul 27 2006 EDT") == date(2006,07,27,4,0,0))
+assert(date("Jul 27 2006 CST") == date(2006,07,27,6,0,0))
+assert(date("Jul 27 2006 CDT") == date(2006,07,27,5,0,0))
+assert(date("Jul 27 2006 MST") == date(2006,07,27,7,0,0))
+assert(date("Jul 27 2006 MDT") == date(2006,07,27,6,0,0))
+assert(date("Jul 27 2006 PST") == date(2006,07,27,8,0,0))
+assert(date("Jul 27 2006 PDT") == date(2006,07,27,7,0,0))
+
+ +

Date Format.  Short dates can use either a "/" or + "-" date separator, but must follow the month/day/year format

+
+assert(date("02-03-04")==date(1904,02,03))
+assert(date("12/25/98")==date(1998,12,25))
+
+ +

Long dates of the form "July 10 1995" can be given with the + year, month, and day in any order, and the year in 2-digit or + 4-digit form. If you use the 2-digit form, the year must be greater + than or equal to 70.

+
+assert(date("Feb-03-04")==date(1904,02,03))
+assert(date("December 25 1998")==date(1998,12,25))
+
+ +

Follow the year with BC or BCE to indicate that the year is + before common era.

+
+assert(date("Feb 3 0003 BC")==date(-2,02,03))
+assert(date("December 25 0001 BC")==date(0,12,25))
+
+ +

Supported ISO 8601 Formats. 

+ +
+
+
YYYY-MM-DD
+ +
+ where YYYY is the year, MM is the month of the year, and DD + is the day of the month. +
+assert(date("2000-12-31")==date(2000,12,31))
+assert(date(" 20001231 ")==date(2000,12,31)) -- Compact version
+
+
+ +
YYYY-DDD
+ +
+ where YYYY is the year, DDD is the day of the year. +
+assert(date("1995-035")==date(1995,02,04))
+assert(date("1995035 ")==date(1995,02,04)) -- Compact version
+
+
+ +
YYYY-WDD-D
+ +
+ where YYYY is the year, DD is the week of the year, D is the + day of the week. +
+assert(date("1997-W01-1")==date(1996,12,30))
+assert(date("  1997W017")==date(1997,01,05)) -- Compact version
+
+
+ +
DATE HH:MM:SS.SSS
+ +
+ Where DATE is the date + format discuss above, HH is the hour, MM is the miute, SS.SSS + is the seconds (fraction is optional). +
+assert(date("1995-02-04 24:00:51.536")==date(1995,2,5,0,0,51.536))
+assert(date("1976-W01-1 12:12:12.123")==date(1975,12,29,12,12,12.123))
+assert(date("1995-035 23:59:59.99999")==date(1995,02,04,23,59,59.99999))
+-- Compact version separated by latin capital letter T
+assert(date("  19950205T000051.536  ")==date(1995,2,5,0,0,51.536))
+assert(date("  1976W011T121212.123  ")==date(1975,12,29,12,12,12.123))
+assert(date(" 1995035T235959.99999  ")==date(1995,02,04,23,59,59.99999))
+
+
+ +
DATE TIME +HH:MM, DATE + TIME -HHMM, + DATE TIME Z,
+ +
+ Where DATE and + TIME is the dateand + time format discuss above. First character is a sign "+" + (east of UTC) or "-" (west of UTC). HH and MM is Hours and + minutes offset. The Z stands for the zero offset. +
+assert(date("1976-W01-1 12:00Z     ")==date(1975,12,29,12))
+assert(date("1976-W01-1 13:00+01:00")==date(1975,12,29,12))
+assert(date("1976-W01-1 0700-0500  ")==date(1975,12,29,12))
+
+
+
+
+
+
+
+ +
+
+
bool_now
+ +
Required boolean value. if + bool_now is false it returns the current local date and time. + if bool_now is true it returns the current UTC date and + time.
+
+
+ +
+
+
int_year
+ +
Required interger value. The year + value.
+ +
var_month
+ +
Required. A parsable month + value.
+ +
int_day
+ +
Required interger value. The day + of month.
+ +
num_hour
+ +
Optional number value. Equal to + the hours value. The default value is 0
+ +
num_min
+ +
Optional number value. Equal to + the minutes value. The default value is 0
+ +
num_sec
+ +
Optional number value. Equal to + the seconds value. The default value is 0
+ +
int_ticks
+ +
Optional interger value. Equal to + the ticks value. The default value is 0
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successthe new dateObject
Failurenil.
+
+ +
Example
+ +
+
+a = date(2006, 8, 13)   assert(a == date("Sun Aug 13 2006"))
+b = date("Jun 13 1999") assert(b == date(1999, 6, 13))
+c = date(1234483200)    assert(c == date("Feb 13 2009"))
+d = date({year=2009, month=11, day=13, min=6})
+        assert(d == date("Nov 13 2009 00:06:00"))
+e = date() assert(e)
+
+
+
+
+
+
+
+ +
+
+
+
+

7. dateObject

+
+
+
dateObject is a table containing date and time + value. It has a metatable for manipulation and retrieval of dates and times. Use + the __call method of date to + construct a dateObject. + +
+
+
+
+

7.1. How + Date and Time are stored in dateObject

+
+
+
Time is stored in dateObject as Ticks or Day + Fraction. Date is stored in dateObject as Day + Number. Ticks is time unit per seconds. For example, if the tick unit is 1000000. + 0.25 seconds is equivalent to 250000 ticks (0.25*1000000). Day number, is the + number days since the epoch, which is January 1, 0001 AD. Example. +
+dobj = date("15:49:59.3669")
+
If the tick unit is 1000000, dobj store this time as +56999366900 ticks and 0 days. +
+((((15*60)+49)*60)+59.3669)*1000000 == 56999366900
+
Example Date and Time: +
+dobj = date("Jan-5-0001 10:30:15")
+
If the tick unit is 1000000, dobj store this date and +time as 37815000000 ticks and 4 days. 4 days becuase: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Day#Date
0Jan 1 0001
1Jan 2 0001
2Jan 3 0001
3Jan 4 0001
4Jan 5 0001
5Jan 6 0001
......
+ +

The default tick unit is 1000000 (micro-second-ticks)

+
+ +
+
+
+
+

7.2. Supported MetaMethods

+
+
+
+ +
+
+
The a < b + operation.
+ +
Returns true if date value of a is later + than date value of b. a > b is equivalent to + b < a.
+ +
The a <= b + operation.
+ +
Returns true if date value of a is later + than or equal to the date value of b. a >= b + is equivalent to b <= a.
+ +
The a == b + operation.
+ +
Returns true if date value of a is equal + equal to the date value of b. a ~= b is + equivalent to not (a == b).
+ +
The a .. b + operation.
+ +
Equivalent to tostring(a) .. + tostring(b).
+ +
The a - b + operation.
+ +
Subtract the date and time value of a to + date and time value of b.
+ +
The a + b + operation.
+ +
Add the date and time value of a to date and + time value of b.
+
+
a and b must be a + parsable date value or an error rises +
+a = date(1521,5,2)
+b = a:copy():addseconds(0.001)
+
+assert((a - b):spanseconds() == -0.001)
+assert((a + b) == (b + a))
+assert(a == (b - date("00:00:00.001")) )
+assert(b == (a + date("00:00:00.001")) )
+
+b:addseconds(-0.01)
+
+assert(a >  b and b <  a)
+assert(a >= b and b <= a)
+assert(a ~= b and (not(a == b)))
+
+a = b:copy()
+
+assert(not (a >  b and b <  a))
+assert(a >= b and b <= a)
+assert(a == b and (not(a ~= b)))
+
+assert((a .. 565369) == (b .. 565369))
+assert((a .. "????") == (b .. "????"))
+                                
+
+
+ +
+
+
+
+

7.3. Method(s) of dateObject

+
+
+
+ + + +
+
+
+
+

7.3.1. adddays

+
+
+
Add days in + dateObject + +
+
+
Syntax
+ +
+
+dateObject:adddays(int_days)
+
+
+ +
Arguments
+ +
+
+
+
int_days
+ +
Required integer value. Days to + add.
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the adjusted dateObject
Failurenil.
+
+ +
Remarks
+ +
If the value is negative, the adjusted dateObject will be earlier.
+ +
Example
+ +
+
+a = date(2000,12,30)
+b = date(a):adddays(3)
+c = date.diff(b,a)
+assert(c:spandays() == 3)
+
+
+
+
+
+ +
+
+
+
+

7.3.2. addhours

+
+
+
Add hours in + dateObject + +
+
+
Syntax
+ +
+
+dateObject:addhours(num_hours)
+
+
+ +
Arguments
+ +
+
+
+
num_hours
+ +
Required number value. Hours to + add.
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the adjusted dateObject
Failurenil.
+
+ +
Remarks
+ +
If the value is negative, the adjusted dateObject will be earlier.
+ +
Example
+ +
+
+a = date(2000,12,30)
+b = date(a):addhours(3)
+c = date.diff(b,a)
+assert(c:spanhours() == 3)
+
+
+
+
+
+ +
+
+
+
+

7.3.3. addminutes

+
+
+
Add minutes in + dateObject + +
+
+
Syntax
+ +
+
+dateObject:addminutes(num_minutes)
+
+
+ +
Arguments
+ +
+
+
+
num_minutes
+ +
Required number value. Minutes to + add.
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the adjusted dateObject
Failurenil.
+
+ +
Remarks
+ +
If the value is negative, the adjusted dateObject will be earlier.
+ +
Example
+ +
+
+a = date(2000,12,30)
+b = date(a):addminutes(3)
+c = date.diff(b,a)
+assert(c:spanminutes() == 3)
+
+
+
+
+
+ +
+
+
+
+

7.3.4. addmonths

+
+
+
Add months in + dateObject + +
+
+
Syntax
+ +
+
+dateObject:addmonths(int_months)
+
+
+ +
Arguments
+ +
+
+
+
int_months
+ +
Required integer value. Months to + add.
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the adjusted dateObject
Failurenil.
+
+ +
Remarks
+ +
If the value is negative, the adjusted dateObject will be earlier.
+ +
Example
+ +
+
+a = date(2000,12,28):addmonths(3)
+assert(a:getmonth() == 3)
+
+
+
+
+
+ +
+
+
+
+

7.3.5. addseconds

+
+
+
Add seconds in + dateObject + +
+
+
Syntax
+ +
+
+dateObject:addseconds(num_sec)
+
+
+ +
Arguments
+ +
+
+
+
num_sec
+ +
Required number value. Seconds to + add.
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the adjusted dateObject
Failurenil.
+
+ +
Remarks
+ +
If the value is negative, the adjusted dateObject will be earlier.
+ +
Example
+ +
+
+a = date(2000,12,30)
+b = date(a):addseconds(3)
+c = date.diff(b,a)
+assert(c:spanseconds() == 3)
+
+
+
+
+
+ +
+
+
+
+

7.3.6. addticks

+
+
+
Add ticks in + dateObject + +
+
+
Syntax
+ +
+
+dateObject:addticks(num_ticks)
+
+
+ +
Arguments
+ +
+
+
+
num_ticks
+ +
Required number value. Ticks to + add.
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the adjusted dateObject
Failurenil.
+
+ +
Remarks
+ +
If the value is negative, the adjusted dateObject will be earlier. For + discussion about ticks see Section 7.1, + “How Date and Time are stored in dateObject.
+ +
Example
+ +
+
+a = date(2000,12,30)
+b = date(a):addticks(3)
+c = date.diff(b,a)
+assert(c:spanticks() == 3)
+
+
+
+
+
+ +
+
+
+
+

7.3.7. addyears

+
+
+
Add years in + dateObject + +
+
+
Syntax
+ +
+
+dateObject:addyears(int_years)
+
+
+ +
Arguments
+ +
+
+
+
int_years
+ +
Required integer value. Years to + add.
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the adjusted dateObject
Failurenil.
+
+ +
Remarks
+ +
If the value is negative, the adjusted dateObject will be earlier.
+ +
Example
+ +
+
+a = date(2000,12,30):addyears(3)
+assert(a:getyear() == (2000+3))
+
+
+
+
+
+ +
+
+
+
+

7.3.8. copy

+
+
+
Returns a new date + object having the same date and time value of dateObject + +
+
+
Syntax
+ +
+
+dateObject:copy()
+
+
+ +
Example
+ +
+
+a = date(2000,12,30)
+b = a:copy()
+assert(a==b)
+
+
+
+
+
+ +
+
+
+
+

7.3.9. fmt

+
+
+
Returns a + formatted version of dateObject. + +
+
+
Syntax
+ +
+
+dateObject:fmt(str_code)
+
+
+ +
Arguments
+ +
+
+
+
str_code
+ +
+ string value. The format string + follows the same rules as the strftime standard C function. + +
+ + +

Table 3. Format Spec

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
SpecDescription
'%a'Abbreviated weekday name (Sun)
'%A'Full weekday name (Sunday)
'%b'Abbreviated month name (Dec)
'%B'Full month name (December)
'%C'Year/100 (19, 20, 30)
'%d'The day of the month as a number (range 1 - 31)
'%g'year for ISO 8601 week, from 00 (79)
'%G'year for ISO 8601 week, from 0000 (1979)
'%h'same as %b
'%H'hour of the 24-hour day, from 00 (06)
'%I'The hour as a number using a 12-hour clock (01 - + 12)
'%j'The day of the year as a number (001 - 366)
'%m'Month of the year, from 01 to 12
'%M'Minutes after the hour 55
'%p'AM/PM indicator (AM)
'%S'The second as a number (59, 20 , 01)
'%u'ISO 8601 day of the week, to 7 for Sunday (7, 1)
'%U'Sunday week of the year, from 00 (48)
'%V'ISO 8601 week of the year, from 01 (48)
'%w'The day of the week as a decimal, Sunday being 0
'%W'Monday week of the year, from 00 (48)
'%y'The year as a number without a century (range 00 to + 99)
'%Y'Year with century (2000, 1914, 0325, 0001)
'%z'Time zone offset, the date object is assumed local + time (+1000, -0230)
'%Z'Time zone name, the date object is assumed local + time
'%\b'Year, if year is in BCE, prints the BCE Year + representation, otherwise result is similar to "%Y" (1 + BCE, 40 BCE) #
'%\f'Seconds including fraction (59.998, 01.123) #
'%%'percent character %
'%r'12-hour time, from 01:00:00 AM (06:55:15 AM); same as + "%I:%M:%S %p"
'%R'hour:minute, from 01:00 (06:55); same as "%I:%M"
'%T'24-hour time, from 00:00:00 (06:55:15); same as + "%H:%M:%S"
'%D'month/day/year from 01/01/00 (12/02/79); same as + "%m/%d/%y"
'%F'year-month-day (1979-12-02); same as "%Y-%m-%d"
'%c'The preferred date and time representation; same as + "%x %X"
'%x'The preferred date representation, same as "%a %b %d + %\b"
'%X'The preferred time representation, same as + "%H:%M:%\f"
'${iso}'Iso format, same as "%Y-%m-%dT%T"
'${http}'http format, same as "%a, %d %b %Y %T GMT"
'${ctime}'ctime format, same as "%a %b %d %T GMT %Y"
'${rfc850}'RFC850 format, same as "%A, %d-%b-%y %T GMT"
'${rfc1123}'RFC1123 format, same as "%a, %d %b %Y %T GMT"
'${asctime}'asctime format, same as "%a %b %d %T %Y"
+
+

+
+
+
+
+ +
Remarks
+ +
Only English names are supported
+ +
Example
+ +
+
+d = date(1582,10,5)
+assert(d:fmt('%D') == d:fmt("%m/%d/%y"))        -- month/day/year from 01/01/00 (12/02/79)
+assert(d:fmt('%F') == d:fmt("%Y-%m-%d"))        -- year-month-day (1979-12-02)
+assert(d:fmt('%h') == d:fmt("%b"))                      -- same as %b (Dec)
+assert(d:fmt('%r') == d:fmt("%I:%M:%S %p"))     -- 12-hour time, from 01:00:00 AM (06:55:15 AM)
+assert(d:fmt('%T') == d:fmt("%H:%M:%S"))        -- 24-hour time, from 00:00:00 (06:55:15)
+assert(d:fmt('%a %A %b %B') == "Tue Tuesday Oct October")
+assert(d:fmt('%C %d') == "15 05", d:fmt('%C %d'))
+
+print(d:fmt[[
+${iso} -- iso
+${http} -- http
+${ctime} -- ctime
+${rfc850} -- rfc850
+${rfc1123} -- rfc1123
+${asctime} -- asctime
+]])
+
+
+ +
Example + (Prints the current date and time)
+ +
+
+-- Prints the current date and time, including time zone
+d = date(false);
+print(d:fmt("Today is %c GMT%z"))
+--> "Today is Tue Oct 31 2000 01:58:14 GMT-0330"
+
+-- Prints the current date and time in ISO format including time zone
+d = date(false);
+print(d:fmt("Today is ${iso}%z"))
+--> "Today is 2000-10-31T01:58:14-0330"
+
+-- Prints the current date and time in ISO format, indicates UTC
+d = date(true);
+print(d:fmt("Today is ${iso}Z"))
+--> "Today is 2000-10-31T05:28:14Z"
+
+
+
+
+
+ +
+
+
+
+

7.3.10. getbias

+
+
+
Assuming dateObject is a local time. Returns the time zone offset. + Returns nil on failure. + +
+
+
Syntax
+ +
+
+dateObject:getbias()
+
+
+ +
Example
+ +
+
+a = date(2^16)
+print(a:getbias())
+
+
+
+
+
+ +
+
+
+
+

7.3.11. getclockhour

+
+
+
Returns the hours + value using a 12-hour clock in a dateObject. + +
+
+
Syntax
+ +
+
+dateObject:getclockhour()
+
+
+ +
Example
+ +
+
+a = date("10:59:59 pm")
+assert(a:getclockhour()==10)
+
+
+
+
+
+ +
+
+
+
+

7.3.12. getdate

+
+
+
Returns the + year, month, and day value in a dateObject. + +
+
+
Syntax
+ +
+
+dateObject:getdate()
+
+
+ +
Example
+ +
+
+a = date(1970, 1, 1)
+y, m, d = a:getdate()
+assert(y == 1970 and m == 1 and d == 1)
+
+
+
+
+
+ +
+
+
+
+

7.3.13. getday

+
+
+
Returns the day of + month value in a dateObject + +
+
+
Syntax
+ +
+
+dateObject:getday()
+
+
+ +
Example
+ +
+
+d = date(1966, 'sep', 6)
+assert(d:getday() == 6)
+
+
+
+
+
+ +
+
+
+
+

7.3.14. getfracsec

+
+
+
Returns the + seconds after the minute (fractional) value in a dateObject. + +
+
+
Syntax
+ +
+
+dateObject:getfracsec()
+
+
+ +
Example
+ +
+
+d = date("Wed Apr 04 2181 11:51:06.996 UTC")
+assert(d:getfracsec() == 6.996)
+
+
+
+
+
+ +
+
+
+
+

7.3.15. gethours

+
+
+
Returns the hours + value in a dateObject + +
+
+
Syntax
+ +
+
+dateObject:gethours()
+
+
+ +
Example
+ +
+
+d = date("Wed Apr 04 2181 11:51:06 UTC")
+assert(d:gethours() == 11)
+
+
+
+
+
+ +
+
+
+
+

7.3.16. getisoweekday

+
+
+
Returns the day of + week (sunday=7, monday=1, ...saturday=6) in a dateObject. + +
+
+
Syntax
+ +
+
+dateObject:getisoweekday()
+
+
+ +
Example
+ +
+
+d = date(1970, 1, 1)
+assert(d:getisoweekday() == 4)
+
+
+
+
+
+ +
+
+
+
+

7.3.17. getisoweeknumber

+
+
+
Returns the ISO + 8601 week number (01 to 53) in a dateObject. Using + the Year-WeekOfYear-DayOfWeek date system + +
+
+
Syntax
+ +
+
+dateObject:getisoweeknumber()
+
+
+ +
Example
+ +
+
+d = date(1975, 12, 29)
+assert(d:getisoweeknumber() == 1)
+assert(d:getisoyear() == 1976)
+assert(d:getisoweekday() == 1)
+d = date(1977, 1, 2)
+assert(d:getisoweeknumber() == 53)
+assert(d:getisoyear() == 1976)
+assert(d:getisoweekday() == 7)
+
+
+
+
+
+ +
+
+
+
+

7.3.18. getisoyear

+
+
+
Returns the ISO + 8601 year in a dateObject. Using the + Year-WeekOfYear-DayOfWeek date system + +
+
+
Syntax
+ +
+
+dateObject:getisoyear()
+
+
+ +
Example
+ +
+
+d = date(1996, 12, 30)
+assert(d:getisoyear() == 1997)
+d = date(1997, 01, 05)
+assert(d:getisoyear() == 1997)
+
+
+
+
+
+ +
+
+
+
+

7.3.19. getminutes

+
+
+
Returns the + minutes after the hour value in a dateObject + +
+
+
Syntax
+ +
+
+dateObject:getminutes()
+
+
+ +
Example
+ +
+
+d = date("Wed Apr 04 2181 11:51:06 UTC")
+assert(d:getminutes() == 51)
+
+
+
+
+
+ +
+
+
+
+

7.3.20. getmonth

+
+
+
Returns the month + value in a dateObject + +
+
+
Syntax
+ +
+
+dateObject:getmonth()
+
+
+ +
Example
+ +
+
+d = date(1966, 'sep', 6)
+assert(d:getmonth() == 9)
+
+
+
+
+
+ +
+
+
+
+

7.3.21. getseconds

+
+
+
Returns the + seconds after the minute value in a dateObject + +
+
+
Syntax
+ +
+
+dateObject:getseconds()
+
+
+ +
Example
+ +
+
+d = date("Wed Apr 04 2181 11:51:06.123 UTC")
+assert(d:getseconds() == 6)
+
+
+
+
+
+ +
+
+
+
+

7.3.22. getticks

+
+
+
Returns the ticks + after the seconds value in a dateObject + +
+
+
Syntax
+ +
+
+dateObject:getticks()
+
+
+ +
Remarks
+ +
For discussion about ticks see Section 7.1, + “How Date and Time are stored in dateObject.
+ +
Example
+ +
+
+d = date("Wed Apr 04 2181 11:51:06.123 UTC")
+assert(d:getticks() == 123000)
+
+
+
+
+
+ +
+
+
+
+

7.3.23. gettime

+
+
+
Returns the + hours, minutes, seconds and ticks value in a dateObject. + +
+
+
Syntax
+ +
+
+dateObject:gettime()
+
+
+ +
Example
+ +
+
+a = date({hour=5,sec=.5,min=59})
+h, m, s, t = a:gettime()
+assert(t == 500000 and s == 0 and m == 59 and h == 5, tostring(a))
+
+
+
+
+
+ +
+
+
+
+

7.3.24. getweekday

+
+
+
Returns the day of + week (sunday=1, monday=2, ...saturday=7) in a dateObject. + +
+
+
Syntax
+ +
+
+dateObject:getweekday()
+
+
+ +
Example
+ +
+
+d = date(1970, 1, 1)
+assert(d:getweekday() == 5)
+
+
+
+
+
+ +
+
+
+
+

7.3.25. getweeknumber

+
+
+
Returns the week + number value in a dateObject. + +
+
+
Syntax
+ +
+
+dateObject:getweeknumber([int_wdaybase])
+
+
+ +
Arguments
+ +
+
+
+
int_wdaybase
+ +
Optional integer value. The + starting day of week (1 for sunday, 2 for monday, ... 7 for + saturday). If omitted the starting day of week is sunday.
+
+
+
+ +
Example
+ +
+
+a = date("12/31/1972")
+b,c = a:getweeknumber(), a:getweeknumber(2)
+assert(b==53 and c==52)
+
+
+
+
+
+ +
+
+
+
+

7.3.26. getyear

+
+
+
Returns the year + value in a dateObject + +
+
+
Syntax
+ +
+
+dateObject:getyear()
+
+
+ +
Example
+ +
+
+d = date(1965, 'jan', 0)
+assert(d:getyear() == 1964)
+
+
+
+
+
+ +
+
+
+
+

7.3.27. getyearday

+
+
+
Returns the day of + year (1-366) in a dateObject. + +
+
+
Syntax
+ +
+
+dateObject:getyearday()
+
+
+ +
Example
+ +
+
+d = date(2181, 1, 12)
+assert(d:getyearday() == 12)
+
+
+
+
+
+ +
+
+
+
+

7.3.28. setday

+
+
+
Sets the day of + month value in dateObject + +
+
+
Syntax
+ +
+
+dateObject:setday(int_mday)
+
+
+ +
Arguments
+ +
+
+
+
int_mday
+ +
integer value. A numeric value + equal to the day of month. The default value is the current day of month
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1966, 'july', 6)
+d:setday(1)
+assert(d == date("1966 july 1"))
+
+
+
+
+
+ +
+
+
+
+

7.3.29. sethours

+
+
+
Sets the hour + value in dateObject + +
+
+
Syntax
+ +
+
+dateObject:sethours(num_hour, num_min, num_sec, num_ticks)
+
+
+ +
Arguments
+ +
+
+
+
num_hour
+ +
number value. The hours value. The + default value is the current hours + value
+ +
num_min
+ +
number value. The minutes after + the hours value. The default value is the + current minutes value
+ +
num_sec
+ +
number value. The seconds after + the minute value. The default value is the + current seconds value
+ +
num_ticks
+ +
number value. The ticks after the + second value. The default value is the current + ticks value
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1984, 12, 3, 4, 39, 54)
+d:sethours(1, 1, 1)
+assert(d == date("1984 DEc 3 1:1:1"))
+
+
+
+
+
+ +
+
+
+
+

7.3.30. setisoweekday

+
+
+
Sets the ISO 8601 + week number value in dateObject. Using the + Year-WeekOfYear-DayOfWeek date system + +
+
+
Syntax
+ +
+
+dateObject:setisoweekday(int_wday)
+
+
+ +
Arguments
+ +
+
+
+
int_wday
+ +
integer value. The day of month. + The default value is the current week + day
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date.isodate(1999, 52, 1)
+d:setisoweekday(7)
+assert(d == date(2000, 1, 02))
+
+
+
+
+
+ +
+
+
+
+

7.3.31. setisoweeknumber

+
+
+
Sets the ISO 8601 + week number value in dateObject. Using the + Year-WeekOfYear-DayOfWeek date system + +
+
+
Syntax
+ +
+
+dateObject:setisoweeknumber(int_week, int_wday)
+
+
+ +
Arguments
+ +
+
+
+
int_week
+ +
integer value. The month value. + The default value is the current + week
+ +
int_wday
+ +
integer value. The day of month. + The default value is the current week + day
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1999, 12, 27)
+d:setisoweeknumber(51, 7)
+assert(d == date(1999, 12, 26))
+
+
+
+
+
+ +
+
+
+
+

7.3.32. setisoyear

+
+
+
Sets the ISO 8601 + year value in dateObject. Using the + Year-WeekOfYear-DayOfWeek date system + +
+
+
Syntax
+ +
+
+dateObject:setisoyear(int_year, int_week, int_wday)
+
+
+ +
Arguments
+ +
+
+
+
int_year
+ +
integer value. The year value. The + default value is the current year
+ +
int_week
+ +
integer value. The month value. + The default value is the current + week
+ +
int_wday
+ +
integer value. The day of month. + The default value is the current week + day
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1999, 12, 27)
+d:setisoyear(2000, 1)
+assert(d == date.isodate(2000,1,1))
+assert(d:getyear() == 2000)
+assert(d:getday() == 3)
+
+
+
+
+
+ +
+
+
+
+

7.3.33. setminutes

+
+
+
Sets the minutes + value in dateObject + +
+
+
Syntax
+ +
+
+dateObject:setminutes(num_min, num_sec, num_ticks)
+
+
+ +
Arguments
+ +
+
+
+
num_min
+ +
number value. The minutes after + the value. The default value is the current + minutes value
+ +
num_sec
+ +
number value. The seconds after + the minute value. The default value is the + current seconds value
+ +
num_ticks
+ +
number value. The ticks after the + second value. The default value is the current + ticks value
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1984, 12, 3, 4, 39, 54)
+d:setminutes(59, 59, 500)
+assert(d == date(1984, 12, 3, 4, 59, 59, 500))
+
+
+
+
+
+ +
+
+
+
+

7.3.34. setmonth

+
+
+
Sets the month + value in dateObject + +
+
+
Syntax
+ +
+
+dateObject:setmonth(var_month, int_mday)
+
+
+ +
Arguments
+ +
+
+
+
var_month
+ +
parsable month value. The + default value is the current month
+ +
int_mday
+ +
integer value. The day of month. + The default value is the current day of + month
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1966, 'july', 6)
+d:setmonth(1)
+assert(d == date("6 jan 1966"))
+
+
+
+
+
+ +
+
+
+
+

7.3.35. setseconds

+
+
+
Sets the seconds + after the minute value in dateObject + +
+
+
Syntax
+ +
+
+dateObject:setseconds(num_sec, num_ticks)
+
+
+ +
Arguments
+ +
+
+
+
num_sec
+ +
number value. The seconds after + the minute value. The default value is the + current seconds value
+ +
num_ticks
+ +
number value. The ticks after the + second value. The default value is the current + ticks value
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1984, 12, 3, 4, 39, 54)
+d:setseconds(59, date.ticks())
+assert(d == date(1984, 12, 3, 4, 40))
+
+
+
+
+
+ +
+
+
+
+

7.3.36. setticks

+
+
+
Sets the ticks + after the second value in dateObject + +
+
+
Syntax
+ +
+
+dateObject:setticks(num_ticks)
+
+
+ +
Arguments
+ +
+
+
+
num_ticks
+ +
number value. The ticks after the + second value. The default value is the current + ticks value
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1984, 12, 3, 4, 39, 54)
+d:setticks(444)
+assert(d == date(1984, 12, 3, 4, 39, 54, 444))
+
+
+
+
+
+ +
+
+
+
+

7.3.37. setyear

+
+
+
Sets the year + value in dateObject + +
+
+
Syntax
+ +
+
+dateObject:setyear(int_year, var_month, int_mday)
+
+
+ +
Arguments
+ +
+
+
+
int_year
+ +
integer value. The year value. The + default value is the current year
+ +
var_month
+ +
The month value. The default value is the + current month
+ +
int_mday
+ +
integer value. The day of month. + The default value is the current day of + month
+
+
+
+ +
Returns
+ +
+ + + + + + + + + + + + +
Successreference to the dateObject
Failurenil.
+
+ +
Example
+ +
+
+d = date(1966, 'july', 6)
+d:setyear(2000)
+assert(d == date("jul 6 2000"))
+
+
+
+
+
+ +
+
+
+
+

7.3.38. spandays

+
+
+
Returns how many + days the dateObject has + +
+
+
Syntax
+ +
+
+dateObject:spandays()
+
+
+ +
Example
+ +
+
+a = date(2181, "aPr", 4, 6, 30, 30, 15000)
+b = date(a):adddays(2)
+c = date.diff(b, a)
+assert(c:spandays() == (2))
+
+
+
+
+
+ +
+
+
+
+

7.3.39. spanhours

+
+
+
Returns how many + hours the dateObject has + +
+
+
Syntax
+ +
+
+dateObject:spanhours()
+
+
+ +
Example
+ +
+
+a = date(2181, "aPr", 4, 6, 30, 30, 15000)
+b = date(a):adddays(2)
+c = date.diff(b, a)
+assert(c:spanhours() == (2*24))
+
+
+
+
+
+ +
+
+
+
+

7.3.40. spanminutes

+
+
+
Returns how many + minutes the dateObject has + +
+
+
Syntax
+ +
+
+dateObject:spanminutes()
+
+
+ +
Example
+ +
+
+a = date(2181, "aPr", 4, 6, 30, 30, 15000)
+b = date(a):adddays(2)
+c = date.diff(b, a)
+assert(c:spanminutes() == (2*24*60))
+
+
+
+
+
+ +
+
+
+
+

7.3.41. spanseconds

+
+
+
Returns how many + seconds the dateObject has + +
+
+
Syntax
+ +
+
+dateObject:spanseconds()
+
+
+ +
Example
+ +
+
+a = date(2181, "aPr", 4, 6, 30, 30, 15000)
+b = date(a):adddays(2)
+c = date.diff(b, a)
+assert(c:spanseconds() == (2*24*60*60))
+
+
+
+
+
+ +
+
+
+
+

7.3.42. spanticks

+
+
+
Returns how many + ticks the dateObject has + +
+
+
Syntax
+ +
+
+dateObject:spanticks()
+
+
+ +
Remarks
+ +
For discussion about ticks see Section 7.1, + “How Date and Time are stored in dateObject.
+ +
Example
+ +
+
+a = date(2181, "aPr", 4, 6, 30, 30, 15000)
+b = date(a):adddays(2)
+c = date.diff(b, a)
+assert(c:spanseconds() == (2*24*60*60))
+
+
+
+
+
+ +
+
+
+
+

7.3.43. tolocal

+
+
+
Assuming dateObject is a utc time. Convert its date and time value to + local time. + +
+
+
Syntax
+ +
+
+dateObject:tolocal()
+
+
+ +
Example
+ +
+
+a = date(2^16)
+b = a:copy():tolocal();
+print(a,b)
+
+
+
+
+
+ +
+
+
+
+

7.3.44. toutc

+
+
+
Assuming dateObject is a local time. Convert its date and time value + to utc time. + +
+
+
Syntax
+ +
+
+dateObject:toutc()
+
+
+ +
Example
+ +
+
+a = date(2^16)
+b = a:copy():toutc();
+print(a,b)
+
+
+
+
+
+
+
+ +
+
+
+
+

8. History

+
+
+
+ +
+
+
v1 (2005)
+ +
Binary module
+ +
v2 (2006)
+ +
Lua module
+
+
+
+ +
+
+
+
+

9. Acknowledgement

+
+
+
+ +

http://alcor.concordia.ca/~gpkatch/gdate-method.html - Date calculation + algorithms is based on this site.

+
+
+ +