Постоянно защищенный модуль
Из Википедии, бесплатной энциклопедии
Перейти к навигации Перейти к поиску
Документация по модулю [ просмотреть ] [ изменить ] [ историю ] [ очистить ]

Этот модуль предоставляет функции даты для использования другими модулями. Поддерживаются даты в григорианском и юлианском календарях с 9999 г. до н.э. до 9999 г. н.э. Календари являются пролептическими - предполагается, что они применяются в любое время без каких-либо отклонений.

Дата с необязательным временем может быть указана в различных форматах и ​​может быть преобразована для отображения с использованием различных форматов, например 1 апреля 2016 г. или 1 апреля 2016 г. Свойства даты включают дату по юлианскому календарю. и его серийная дата по григорианскому календарю, а также день недели и день года.

Даты можно сравнивать (например, date1 <= date2) и использовать с добавлением или вычитанием (например, date + '3 months'). Разницу между двумя датами можно определить с помощью date1 - date2. Эти операции работают с датами как по григорианскому, так и по юлианскому календарю, но date1 - date2равны нулю, если две даты используют разные календари.

Модуль предоставляет следующие элементы.

Ниже приведены примеры использования модуля:

Форматированный вывод

Дата может быть отформатирована как текст.

local  Date  =  require ( 'Модуль: Дата' ). _Date local  text  =  Date ( 2016 ,  7 ,  1 ): text ()  - результат: '1 июля 2016' local  text  =  Date ( 2016 ,  7 ,  1 ): text ( '% -d% B' )  - результат это '1 июля' local  text  =  Date ( '1 июля 2016' ): text ( 'mdy' ) - результат "1 июля 2016 г."

Доступны следующие упрощенные коды форматирования.

Доступны следующие коды форматирования (аналогичные strftime ).

Кроме того, можно использовать (где любое свойство даты).%{property}property

Например, Date('1 Feb 2015 14:30:45 A.D.')имеет следующие свойства.

Доступны некоторые ярлыки. Учитывая date = Date('1 Feb 2015 14:30'), были бы достигнуты следующие результаты.

Юлианская дата

Ниже приведен пример преобразования даты по юлианскому календарю в дату с последующим получением информации о дате.

- Код - Дата  результата =  требуется ( 'Модуль: Дата' ). _Date date  =  Дата ( 'juliandate' ,  320 ) число  =  дата . GSD  - -1721105 номер  =  дата . jd  - 320 текст  =  дата . dayname  - суббота text  =  date : text ()  - 9 октября 4713 г. & nbsp; BC text  =  date : text( '% Y-% m-% d' )  - 4713-10-09 text  =  date : text ( '% {era}% Y-% m-% d' )  - BC 4713-10-09 text  =  date : text ( '% Y-% m-% d% {era}' )  - 4713-10-09 & nbsp; BC text  =  date : text ( '% Y-% m-% d% {era}' ,  ' era = BCE ' )  - 4713-10-09 & nbsp; BCE text  =  date : text ( '% Y-% m-% d ' ,  ' era = BCNEGATIVE ')  - -4712-10-09 текст  = date : text ( '% Y-% m-% d' ,  'era = BCMINUS' )  - −4712-10-09 (используется МИНУСНЫЙ ЗНАК Юникода U + 2212) text  =  Date ( 'juliandate' , 320 ): text ( '% {gsd}% {jd}' )  - -1721105 320 text  =  Дата ( '9 октября 4713 г. до н.э.' ): text ( '% {gsd}% {jd}' )  - -1721105 320 text  =  Дата ( - 4712 , 10 , 9 ): текст ('% {gsd}% {jd}' )  - -1721105 320

Различия в датах

Разницу между двумя датами можно определить с помощью date1 - date2. Результат действителен, если обе даты используют григорианский календарь или если обе даты используют юлианский календарь, в противном случае результат равен нулю. Возраст и продолжительность могут быть рассчитаны по разнице дат.

Например:

- Код - Дата  результата =  требуется ( 'Модуль: Дата' ). _DATE date1  =  Дата ( '21 марта 2015' ) date2  =  Дата ( '4 декабря 1999' ) дифф  =  date1  -  date2 d  =  дифф . age_days  - 5586 г ,  м ,  д  =  разн . лет ,  разн . месяцев ,  разн . дней - 15, 3, 17 (15 лет + 3 месяца + 17 дней) y ,  m ,  d  =  diff : age ( 'ymd' )  - 15, 3, 17 y ,  m ,  w ,  d  =  diff : age ( 'ymwd' )  - 15, 3, 2, 3 (15 лет + 3 месяца + 2 недели + 3 дня) y ,  m ,  w ,  d  =  diff : duration ( 'ymwd' )  - 15, 3, 2, 4 d  =  разница : продолжительность( 'd' )  - 5587 (продолжительность включает последний день)

Разница в датах содержит исходные даты, за исключением того, что они меняются местами diff.date1 >= diff.date2( diff.date1это более поздняя дата). Это показано ниже.

date1  =  Дата ( '21 марта 2015' ) date2  =  Дата ( '4 Декабрь 1999' ) дифф  =  date1  -  date2 отр  =  дифф . isnegative  - ложный текст  =  diff . date1 : text ()  - 21 марта 2015 г. text  =  diff . date2 : текст ()  - 4 декабря 1999 дифф  =  date2  -  date1 отр  =  дифф .isnegative  - true (даты поменялись местами) text  =  diff . date1 : text ()  - 21 марта 2015 г. text  =  diff . date2 : text ()  - 4 декабря 1999 г.

Разница в датах также имеет разницу во времени:

date1  =  Дата ( '8 марта 2016 0:30:45' ) дата2  =  Дата ( '19 января 2014 22:55' ) Diff  =  date1  -  дата2 у ,  м ,  д  =  разн . лет ,  разн . месяцев ,  разн . дней  - 2, 1, 17 Н ,  М ,  S  =  разн . часов ,  разн . минут ,  разн . секунды - 1, 35, 45

Разница в датах может быть добавлена ​​к дате или вычтена из даты.

date1  =  Дата ( '8 марта 2016 0:30:45' ) date2  =  Дата ( '19 января 2014 22:55' ) дифф  =  date1  -  date2 date3  =  date2  +  дифференциал date4  =  date1  -  дифф текст  =  date3 : текст ( ' ymd hms ' )  - 2016-03-08 00:30:45 text  =  date4 : text ( ' ymd hms ' )  - 2014-01-19 22:55:00 equal  =  ( date1 ==  date3 )  - истинные равные  =  ( дата2  ==  date4 )  - истинно

Методы возраста и продолжительности разницы в датах принимают код, который определяет компоненты, которые должны быть возвращены. Дополнительный день включен в метод продолжительности, потому что он включает последний день.

- Функции даты для использования другими модулями.- I18N и часовые пояса не поддерживаются.local  MINUS  =  '-'  - Unicode U + 2212 МИНУСНЫЙ ЗНАКлокальный  этаж  =  math.floorlocal  Date ,  DateDiff ,  diffmt  - форвардные объявленияlocal  uniq  =  {  'уникальный идентификатор'  }локальная  функция  is_date ( t )- Система, используемая для создания даты только для чтения, означает, что нет уникальных- метатаблица, удобная для проверки. тип возврата ( t )  ==  'table'  и  t . _id  ==  uniqконецлокальная  функция  is_diff ( t ) тип возврата ( t )  ==  'table'  и  getmetatable ( t )  ==  diffmtконецлокальная  функция  _list_join ( список ,  sep )вернуть  table.concat ( список ,  sep )конецлокальная  коллекция функций  ()- Верните стол для хранения предметов.return  {п  =  0 ,добавить  =  функция  ( сам ,  элемент )я . n  =  себя . п  +  1сам [ сам . n ]  =  элементконец ,join  =  _list_join ,}конецлокальная  функция  strip_to_nil ( текст )- Если текст является строкой, вернуть его обрезанное содержимое или ноль, если он пуст.- В противном случае вернуть текст (удобно, когда поля даты предоставляются из- другой модуль, который может передавать строку, число или другой тип).если  type ( text )  ==  'string',  тотекст  =  текст : совпадение ( '(% S .-)% s * $' )конец текст возвратаконецлокальная  функция  is_leap_year ( год ,  имя )- Вернуть true, если год високосный.если  calname  ==  'Julian',  тогдавозвращение  год  %  4  ==  0конецдоходность  ( год  %  4  ==  0  и  год  %  100  ~ =  0 )  или  год  %  400  ==  0конецлокальная  функция  days_in_month ( год ,  месяц ,  calname )- Возвращает количество дней (1..31) в данном месяце (1..12).если  month  ==  2  и  is_leap_year ( год ,  имя ),  товозврат  29конецreturn  ({  31 ,  28 ,  31 ,  30 ,  31 ,  30 ,  31 ,  31 ,  30 ,  31 ,  30 ,  31  }) [ месяц ]конецлокальная  функция  h_m_s ( время )- Возврат часов, минут, секунд, извлеченных из доли дня.время  =  этаж ( время  *  24  *  3600  +  0,5 )  - количество секундместная  секунда  =  время  %  60время  =  этаж ( время  /  60 )возвратный  этаж ( время  /  60 ),  время  %  60 ,  секундаконецлокальная  функция  hms ( дата )- Возвращает долю дня от даты, где (0 <= дробь <1)- если значения действительны, но могут быть любыми, если они находятся вне диапазона.возврат  ( дата . час  +  ( дата . минута  +  дата . секунда  /  60 )  /  60 )  /  24конецлокальная  функция  julian_date ( дата )- Возврат jd, jdz из даты по юлианскому или григорианскому календарю, где- jd = дата по юлианскому календарю и ее дробная часть равна нулю в полдень- jdz = то же самое, но предположим, что время 00:00:00, если время не указано- http://www.tondering.dk/claus/cal/julperiod.php#formula- Тестирование показывает, что это работает для всех дат с -9999 по 9999 год!- JDN 0 - это 24-часовой период, начинающийся в полдень понедельника по всемирному координированному времени.- 1 января 4713 г. до н.э. = (-4712, 1, 1) по юлианскому календарю- 24 ноября 4714 г. до н.э. = (-4713, 11, 24) по григорианскому календарюместное  смещениеместный  а  =  этаж (( 14  -  числа . мес. ) / 12 )местный  y  =  дата . год  +  4800  -  аесли  дата . calendar  ==  'Julian',  затемoffset  =  floor ( y / 4 )  -  32083ещесмещение  =  этаж ( г / 4 )  -  этаж ( г / 100 )  +  этаж ( г / 400 )  -  32045конецместный  м  =  дата . месяц  +  12 * а  -  3местный  jd  =  дата . день  +  пол (( 153 * м  +  2 ) / 5 )  +  365 * y  +  смещениеесли  дата . время  тогдаJD  =  JD  +  HMS ( дата )  -  0,5вернуть  jd ,  jdконецвозврат  jd ,  jd  -  0,5конецлокальная  функция  set_date_from_jd ( дата )- Установите поля даты таблицы из ее поля даты по юлианскому календарю.- Вернуть истину, если дата действительна.- http://www.tondering.dk/claus/cal/julperiod.php#formula- Это обрабатывает пролептические юлианский и григорианский календари.- Отрицательные юлианские даты не определены, но работают.местное  имя  =  дата . календарьлокальный  минимум ,  максимум  - минимальные / максимальные пределы для диапазонов дат от -9999-01-01 до 9999-12-31если  calname  ==  'Gregorian',  тогданизкий ,  высокий  =  - 1930999,5 ,  5373484,49999elseif  calname  ==  'Julian'  тогданизкий ,  высокий  =  - 1931076,5 ,  5373557,49999ещевозвращатьсяконецместный  jd  =  дата . jdесли  нет  ( type ( jd )  ==  'number'  и  low  <=  jd  и  jd  <=  high ),  товозвращатьсяконецместный  jdn  =  этаж ( jd )если  дата . время  тогдаместное  время  =  юлианский день  -  JDN  - 0 <= время <1если  время  > =  0,5,  то  - если в полночь следующего дня или позжеjdn  =  jdn  +  1время  =  время  -  0,5ещевремя  =  время  +  0,5конецдата . час ,  дата . минута ,  дата . second  =  h_m_s ( время )ещедата . второй  =  0дата . минута  =  0дата . час  =  0конецместный  б ,  весли  calname  ==  'Julian',  тогдаб  =  0с  =  jdn  +  32082иначе  - григорианскийместный  a  =  jdn  +  32044b  =  этаж (( 4 * a  +  3 ) / 146097 )c  =  a  -  этаж ( 146097 * b / 4 )конецместный  d  =  этаж (( 4 * c  +  3 ) / 1461 )местный  e  =  c  -  этаж ( 1461 * d / 4 )местный  m  =  этаж (( 5 * e  +  2 ) / 153 )дата . день  =  e  -  этаж (( 153 * m  +  2 ) / 5 )  +  1дата . месяц  =  м  +  3  -  12 * пол ( м / 10 )дата . год  =  100 * b  +  d  -  4800  +  этаж ( м / 10 )вернуть  истинуконецлокальная  функция  fix_numbers ( числа ,  y ,  m ,  d ,  H ,  M ,  S ,  partial ,  hastime ,  calendar )- Поместите результат нормализации заданных значений в номера таблиц.- Результат будет иметь допустимые значения m, d, если y действительно; звонящий проверяет y.- Соблюдается логика PHP mktime, где m или d могут быть равны нулю, чтобы означать- предыдущий блок, -1 - предыдущий и т. д.- Положительные значения переносятся.местная  датаесли  нет  ( 1  <=  m  и  m  <=  12 ),  тоdate  =  Дата ( y ,  1 ,  1 )если  не  дата,  то  верните  конецдата  =  дата  +  (( m  -  1 )  ..  'm' )y ,  m  =  дата . год ,  дата . месяцконецместные  days_hmsесли  не  частичный,  тоесли  hastime  и  Н  и  М  и  S ,  тоесли  нет  ( 0  <=  H  и  H  <=  23  и0  <=  M  и  M  <=  59  и0  <=  S  и  S  <=  59 ),  тогдаdays_hms  =  hms ({  час  =  Ч ,  минута  =  М ,  секунда  =  С  })конецконецесли  days_hms  или  нет  ( 1  <=  d  и  d  <=  days_in_month ( y ,  m ,  calendar )),  тоdate  =  date  или  Date ( y ,  m ,  1 )если  не  дата,  то  верните  конецdate  =  date  +  ( d  -  1  +  ( days_hms  или  0 ))y ,  m ,  d  =  дата . год ,  дата . месяц ,  число . деньесли  days_hms,  тоH ,  M ,  S  =  дата . час ,  дата . минута ,  дата . второйконецконецконецчисла . год  =  yчисла . месяц  =  мчисла . день  =  десли  days_hms,  то- Не устанавливайте H, если он не был действительным, потому что действительный H установит время.числа . час  =  Hчисла . минута  =  Mчисла . второй  =  Sконецконецлокальная  функция  set_date_from_numbers ( дата ,  числа ,  параметры )- Установить поля таблицы даты из числовых значений.- Вернуть истину, если дата действительна.если  type ( числа )  ~ =  'table',  товозвращатьсяконецместный  y  =  числа . год  или  дату . годместный  m  =  числа . месяц  или  число . месяцместный  d  =  числа . день  или  дату . деньместный  H  =  числа . часместный  M  =  числа . минута  или  дата . минута  или  0местный  S  =  числа . второй  или  свидание . второй  или  0местное  need_fixесли  y  и  m  и  d,  тодата . частичный  =  нольесли  нет  ( - 9999  <=  y  и  y  <=  9999  и1  <=  m  и  m  <=  12  и1  <=  д  и  д  <=  Days_in_Month ( у ,  м ,  дата . Календарь )) ,  тоесли  не  дата . want_fix  тогдавозвращатьсяконецneed_fix  =  trueконециначе, если  y  и  дата . частичный  тогдаесли  d  или  нет  ( - 9999  <=  y  и  y  <=  9999 ),  товозвращатьсяконецесли  m,  а  не  ( 1  <=  m  и  m  <=  12 ),  тоесли  не  дата . want_fix  тогдавозвращатьсяконецneed_fix  =  trueконецещевозвращатьсяконецесли  дата . частичный  тогдаH  =  nil  - игнорировать в любое времяM  =  нольS  =  нольещеесли  H,  то- Невозможно установить M или S, не установив также H.дата . hastime  =  trueещеH  =  0конецесли  нет  ( 0  <=  H  и  H  <=  23  и0  <=  M  и  M  <=  59  и0  <=  S  и  S  <=  59 ),  тогдаесли  дата . want_fix  тогдаneed_fix  =  trueещевозвращатьсяконецконецконецдата . want_fix  =  нольесли  need_fix  тоfix_numbers ( числа ,  y ,  m ,  d ,  H ,  M ,  S ,  дата . частичное ,  дата . hastime ,  дата . календарь )вернуть  set_date_from_numbers ( дата ,  числа ,  параметры )конецдата . год  =  y  - от -9999 до 9999 ('n BC' → год = 1 - n)дата . month  =  m  - от 1 до 12 (может быть нулевым, если частично)дата . день  =  d  - от 1 до 31 (* = ноль, если частично)дата . час  =  H  - от 0 до 59 (*)дата . минута  =  M  - от 0 до 59 (*)дата . второй  =  S  - от 0 до 59 (*)если  type ( options )  ==  'table',  тодля  _ ,  k  в  ipairs ({  'am' ,  'era' ,  'format'  })  сделайтеесли  варианты [ k ],  тодата . options [ k ]  =  options [ k ]конецконецконецвернуть  истинуконецлокальная  функция  make_option_table ( options1 ,  options2 )- Если options1 является строкой, вернуть таблицу с ее настройками, или- если это таблица, используйте ее настройки.- Отсутствующие параметры устанавливаются из таблицы options2 или значений по умолчанию.- Если используется значение по умолчанию, устанавливается флаг, чтобы вызывающий знал, что значение не было установлено намеренно.- Допустимые настройки параметров:- am: "am", "am", "AM", "AM"- «pm», «pm», «PM», «PM» (каждое имеет то же значение, что и соответствующий пункт выше)- эра: BCMINUS, BCNEGATIVE, BC, BC, BCE, BCE, AD, AD, CE, CE.- Вариант am = 'am' не означает, что сейчас AM; это означает, что используется "am" или "pm", в зависимости от часа,- и am = 'pm' имеет то же значение.- Аналогично, era = 'BC' означает, что 'BC' используется, если год <= 0.- BCMINUS отображает МИНУС, если год <0 и формат отображения не включает% {era}.- BCNEGATIVE аналогично, но отображает дефис.локальный  результат  =  {по  умолчанию  =  {}  }если  type ( options1 )  ==  'table',  торезультат . am  =  options1 . являюсьрезультат . era  =  options1 . эраelseif  type ( options1 )  ==  'строка',  затем- Пример: «am: AM era: BC» или «am = AM era = BC».для  элемента  в  options1 : gmatch ( '% S +' )  dolocal  lhs ,  rhs  =  item : match ( '^ (% w +) [: =] (. +) $' )если  lhs  тогдарезультат [ lhs ]  =  rhsконецконецконецoptions2  =  type ( options2 )  ==  'table'  и  options2  или  {}местные  значения по умолчанию  =  {  am  =  'am' ,  era  =  'BC'  }для  к ,  v  в  паре ( по умолчанию )  делаетесли  не  результат [ k ],  тоесли  options2 [ k ],  торезультат [ k ]  =  options2 [ k ]ещерезультат [ k ]  =  vрезультат . по умолчанию [ k ]  =  истинаконецконецконецвернуть  результатконецlocal  ampm_options  =  {- lhs = вводимый текст принимается как опция am / pm- rhs = внутренний код[ 'am' ]  =  'am' ,[ 'AM' ]  =  'AM' ,[ 'am' ]  =  'am' ,[ 'AM' ]  =  'AM' ,[ 'pm' ]  =  'am' ,  - то же, что и am[ 'PM' ]  =  'AM' ,[ 'pm' ]  =  'am' ,[ 'PM' ]  =  'AM' ,}local  era_text  =  {- Текст для отображения эпохи с положительным годом (после настройки- заменив год на 1 - год, если date.year <= 0).- options.era = {год <= 0, год> 0}[ 'BCMINUS' ]  =  {  'BC'  ,  ''  ,  isbc  =  true ,  sign  =  MINUS  },[ 'BCNEGATIVE' ]  =  {  'BC'  ,  ''  ,  isbc  =  true ,  sign  =  '-'  },[ 'BC' ]  =  {  'BC'  ,  ''  ,  isbc  =  true  },[ 'BC' ]  =  {  'BC'  ,  ''  ,  isbc  =  true  },[ 'BCE' ]  =  {  'BCE'  ,  ''  ,  isbc  =  true  },[ 'BCE' ]  =  {  'BCE' ,  ''  ,  isbc  =  true  },[ 'AD' ]  =  {  'BC'  ,  'AD'  },[ 'AD' ]  =  {  'BC'  ,  'AD'  },[ 'CE' ]  =  {  'BCE'  ,  'CE'  },[ 'CE' ]  =  {  'BCE' ,  'CE'  },}локальная  функция  get_era_for_year ( эра ,  год )return  ( era_text [ era ]  или  era_text [ 'BC' ]) [ год  >  0  и  2  или  1 ]  или  ""конецлокальная  функция  strftime ( дата ,  формат ,  параметры )- Дата возврата, отформатированная в виде строки с использованием кодов, аналогичных этим- в библиотечной функции C strftime.локальный  sformat  =  string.formatместные  ярлыки  =  {[ '% c' ]  =  '% -I:% M% p% -d% B% -Y% {era}' ,  - дата и время: 14:30 1 апреля 2016 г.[ '% x' ]  =  '% -d% B% -Y% {era}' ,  - дата: 1 апреля 2016 г.[ '% X' ]  =  '% -I:% M% p' ,  - время: 14:30}если  ярлыки [ формат ],  тоformat  =  ярлыки [ формат ]конецместные  коды  =  {a  =  {  field  =  'dayabbr'  },A  =  {  field  =  'dayname'  },b  =  {  field  =  'monthabbr'  },B  =  {  field  =  'monthname'  },u  =  {  fmt  =  '% d'  ,  field  =  'dowiso'  },w  =  {  fmt  =  '% d'  ,  field  =  'dow'  },d  =  {  fmt  =  '% 02d' ,  fmt2  =  '% d' ,  field  =  'day'  },m  =  {  fmt  =  '% 02d' ,  fmt2  =  '% d' ,  field  =  'month'  },Y  =  {  fmt  =  '% 04d' ,  fmt2  =  '% d' ,  field  =  'year'  },H  =  {  fmt  =  '% 02d' ,  fmt2  =  '% d' ,  field  =  'hour'  },M  =  {  fmt  =  '% 02d' ,  fmt2  =  '% d' ,  field  =  'minute'  },S  =  {  fmt  =  '% 02d' ,  fmt2  =  '% d' ,  field  =  'second'  },j  =  {  fmt  =  '% 03d' ,  fmt2  =  '% d' ,  field  =  'dayofyear'  },I  =  {  fmt  =  '% 02d' ,  fmt2  =  '% d' ,  field  =  'hour' ,  special  =  'hour12'  },p  =  {  field  =  'hour' ,  special  =  'am'  },}options  =  make_option_table ( параметры ,  дата . параметры )локальный  amopt  =  параметры . являюсьlocal  eraopt  =  параметры . эралокальная  функция  replace_code ( пробелы ,  модификатор ,  идентификатор )местный  код  =  коды [ id ]если  код,  томестный  fmt  =  код . fmtесли  модификатор  ==  '-'  и  код . fmt2  тогдаfmt  =  код . fmt2конецместное  значение  =  дата [ код . поле ]если  не  значение,  тоreturn  nil  - неопределенное поле в частичной датеконецместный  специальный  =  код . специальныйесли  особенный,  тоесли  special  ==  'hour12',  тогдазначение  =  значение  %  12значение  =  значение  ==  0  и  12  или  значениеelseif  special  ==  'am'  тогдаlocal  ap  =  ({[ 'am' ]  =  {  'am' ,  'pm'  },[ 'AM' ]  =  {  'AM' ,  'PM'  },[ 'AM' ]  =  {  'AM' ,  'PM'  },}) [ ampm_options [ amopt ]]  или  {  'am' ,  'pm'  }return  ( пробелы  ==  ''  и  ''  или  '& nbsp;' )  ..  ( значение  <  12  и  ap [ 1 ]  или  ap [ 2 ])конецконецесли  код . field  ==  'year'  тогдаместный  знак  =  ( era_text [ eraopt ]  или  {}). знакесли  не  знак  или  формат : find ( '% {era}' ,  1 ,  true ),  тознак  =  ''если  значение  <=  0,  тоvalue  =  1  -  значениеконецещеесли  значение  > =  0,  тознак  =  ''ещезначение  =  - значениеконецконецвернуть  пробелы  ..  знак  ..  sformat ( fmt ,  значение )конецвернуть  пробелы  ..  ( fmt  и  sformat ( fmt ,  value )  или  значение )конецконецлокальная  функция  replace_property ( пробелы ,  id )если  id  ==  'era',  то- Особый случай, поэтому можно использовать опцию местной эпохи.локальный  результат  =  get_era_for_year ( eraopt ,  дата . год )если  результат  ==  ''  товернуться  ''конецreturn  ( пробелы  ==  ''  и  ''  или  '& nbsp;' )  ..  результатконецлокальный  результат  =  дата [ id ]если  тип ( результат )  ==  'строка',  товернуть  пробелы  ..  результатконецесли  type ( result )  ==  'number',  товернуть  пробелы  ..  tostring ( результат )конецесли  type ( result )  ==  'boolean',  товернуть  пробелы  ..  ( результат  и  '1'  или  '0' )конец- Это происходит, если id является неопределенным полем в частичной дате или является именем функции.вернуть  нольконецместный  PERCENT  =  ' \ 127 PERCENT \ 127 'возврат  ( формат: gsub ( '%%%%' ,  PERCENT ): gsub ( '(% s ​​*) %% {(% w +)}' ,  replace_property ): gsub ( '(% s ​​*) %% (% -?) (% a)' ,  replace_code ): gsub ( PERCENT ,  '%%' ))конецлокальная  функция  _date_text ( дата ,  fmt ,  параметры )- Вернуть отформатированную строку, представляющую заданную дату.если  не  is_date ( дата ),  тоerror ( 'date: text: нужна дата (используйте "date: text ()" с двоеточием)' ,  2 )конецесли  type ( fmt )  ==  'string'  и  fmt : match ( '% S' ),  тоесли  fmt : find ( '%' ,  1 ,  true ),  товернуть  strftime ( дата ,  fmt ,  параметры )конецelseif  дата . частичный  тогдаfmt  =  дата . месяц  и  "мой"  или  "у"ещеfmt  =  'dmy'если  дата . время  тогдаfmt  =  ( date . second  >  0  и  'hms'  или  'hm' )  ..  fmtконецконецлокальная  функция  bad_format ()- Для согласованности с другими форматами, верните заданный формат.- (или очищенный формат, если оригинал не был строкой), если он недействителен.вернуть  мв . текст . Nowiki ( FMT )конецесли  дата . частичный  тогда- Игнорировать дни в стандартных форматах, например ymd.если  fmt  ==  'ym'  или  fmt  ==  'ymd',  тогдаfmt  =  дата . месяц  и  "% Y-% m% {era}"  или  "% Y% {era}"elseif  fmt  ==  'my'  или  fmt  ==  'dmy'  или  fmt  ==  'mdy'  тогдаfmt  =  дата . месяц  и  "% B% -Y% {era}"  или  "% -Y% {era}"elseif  fmt  ==  'y'  тогдаfmt  =  дата . месяц  и  "% -Y% {эра}"  или  "% -Y% {эра}"ещевернуть  bad_format ()конецвернуть  strftime ( дата ,  fmt ,  параметры )конецлокальная  функция  hm_fmt ()local  plain  =  make_option_table ( параметры ,  дата . параметры ). по умолчанию . являюсьвернуть  простой  и  '% H:% M'  или  '% -I:% M% p'конецlocal  need_time  =  date . времяместный  t  =  collection ()для  элемента  в  fmt : gmatch ( '% S +' )  doместный  жесли  item  ==  'hm',  тогдаf  =  hm_fmt ()need_time  =  falseelseif  item  ==  'hms'  тогдаf  =  '% H:% M:% S'need_time  =  falseelseif  item  ==  'ymd'  тогдаf  =  '% Y-% m-% d% {era}'elseif  item  ==  'mdy'  тогдаf  =  '% B% -d,% -Y% {era}'elseif  item  ==  'dmy'  тогдаf  =  '% -d% B% -Y% {era}'ещевернуть  bad_format ()конецt : добавить ( f )конецfmt  =  t : присоединиться ( '' )если  need_time  тогдаfmt  =  hm_fmt ()  ..  ''  ..  fmtконецвернуть  strftime ( дата ,  fmt ,  параметры )конецlocal  day_info  =  {- 0 = вс до 6 = сб[ 0 ]  =  {  'Sun' ,  'Sunday'  },{  'Пн' ,  'Понедельник'  },{  'Вт' ,  'вторник'  },{  'Среда' ,  'среда'  },{  'Thu' ,  'Thursday'  },{  'Пт' ,  'Пятница'  },{  'Sat' ,  'Saturday'  },}local  month_info  =  {- 1 = с января по 12 = декабрь{  'Январь' ,  'Январь'  },{  'Feb' ,  'February'  },{  'Mar' ,  'March'  },{  'Apr' ,  'April'  },{  'May' ,  'May'  },{  'Июнь' ,  'июнь'  },{  'Июль' ,  'июль'  },{  'Aug' ,  'August'  },{  'Sep' ,  'September'  },{  'Oct' ,  'October'  },{  'Nov' ,  'November'  },{  'Dec' ,  'December'  },}локальная  функция  name_to_number ( текст ,  перевод )если  type ( text )  ==  'string',  тоreturn  translate [ текст : lower ()]конецконецлокальная  функция  номер_дня ( текст )return  name_to_number ( текст ,  {солнце  =  0 ,  воскресенье  =  0 ,пн  =  1 ,  понедельник  =  1 ,Вт  =  2 ,  вторник  =  2 ,ср  =  3 ,  среда  =  3 ,чт  =  4 ,  четверг  =  4 ,пт  =  5 ,  пятница  =  5 ,сб  =  6 ,  суббота  =  6 ,})конецлокальная  функция  month_number ( текст )return  name_to_number ( текст ,  {январь  =  1 ,  январь  =  1 ,февраль  =  2 ,  февраль  =  2 ,мар  =  3 ,  марш  =  3 ,апр  =  4 ,  апрель  =  4 ,май  =  5 ,июн  =  6 ,  июнь  =  6 ,июл  =  7 ,  июль  =  7 ,Августе  =  8 ,  август  =  8 ,Сентябрь  =  9 ,  сентябрь  =  9 ,  сентябрь  =  9 ,Октябрь  =  10 ,  октябрь  =  10 ,ноя  =  11 ,  ноябрь  =  11 ,декабрь  =  12 ,  декабрь  =  12 ,})конецлокальная  функция  _list_text ( список ,  fmt )- Вернуть список отформатированных строк из списка дат.если  не  type ( list )  ==  'table',  тогдаerror ( 'дата: список: текст: нужен "список: текст ()" с двоеточием' ,  2 )конецлокальный  результат  =  {  join  =  _list_join  }для  i ,  дата  в  ipairs ( список )  делатьрезультат [ i ]  =  дата : текст ( fmt )конецвернуть  результатконецлокальная  функция  _date_list ( дата ,  спецификация )- Вернуть возможно пустую нумерованную таблицу дат, соответствующих спецификации.- Даты в списке расположены в порядке возрастания (сначала самая старая дата).- Спецификация должна быть строкой вида «<количество> <день> <op>».- где каждый элемент является необязательным и- count = количество требуемых элементов в списке- день = аббревиатура или название, например Понедельник или Понедельник.- op =>,> =, <, <= (по умолчанию> означает после даты)- Если счетчик не указан, список предназначен для указанных дней в дате месяца.- День по умолчанию - это день даты.- В спецификации также может быть положительное или отрицательное число:- -5 эквивалентно '5 <'- 5 эквивалентно «5», что означает «5>».если  не  is_date ( дата ),  тоerror ( 'date: list: нужна дата (используйте "date: list ()" с двоеточием)' ,  2 )конецлокальный  список  =  {  text  =  _list_text  }если  дата . частичный  тогда список возвратаконецлокальный  счетчик ,  смещение ,  операцияlocal  ops  =  {[ '> =' ]  =  {  before  =  false ,  include  =  true  },[ '>' ]  =  {  before  =  false ,  include  =  false  },[ '<=' ]  =  {  before  =  true  ,  include  =  true  },[ '<' ]  =  {  before  =  true  ,  include  =  false  },}если  спецификация,  тоесли  type ( spec )  ==  'number',  тоcount  =  floor ( spec  +  0,5 )если  count  <  0,  токол  =  - подсчетоперация  =  ops [ '<' ]конецelseif  type ( spec )  ==  'строка',  затемместное  число ,  день ,  op  =  spec : match ( '^% s * (% d *)% s * (% a *)% s * ([<> =] *)% s * $' )если  не  число,  то список возвратаконецесли  num  ~ =  ''  токол  =  ToNumber ( Num )конецесли  день  ~ =  ''  толокальные  доу  =  DAY_NUMBER ( день : GSUB ( '[Ss] $' ,  '' ))  - принимать во множественные дниесли  не  доу,  то список возвратаконецoffset  =  dow  -  дата . доуконецoperation  =  ops [ op ]еще список возвратаконецконецсмещение  =  смещение  или  0операция  =  операция  или  ОПС [ «>» ]местное  datefrom ,  dayfirst ,  daylastесли  операция . до  этогоесли  смещение  >  0  или  ( смещение  ==  0,  а  не  операция . включить ),  тосмещение  =  смещение  -  7конецесли  посчитать  тоесли  count  >  1,  тосмещение  =  смещение  -  7 * ( количество  -  1 )конецdatefrom  =  дата  +  смещениеещеdaylast  =  дата . день  +  смещениеdayfirst  =  daylast  %  7если  dayfirst  ==  0,  тоdayfirst  =  7конецконецещеесли  смещение  <  0  или  ( смещение  ==  0,  а  не  операция . включить ),  тосмещение  =  смещение  +  7конецесли  посчитать  тоdatefrom  =  дата  +  смещениеещеdayfirst  =  дата . день  +  смещениеdaylast  =  дата . месячные дниконецконецесли  не  считать  тоесли  daylast  <  dayfirst,  то список возвратаконецcount  =  floor (( daylast  -  dayfirst ) / 7 )  +  1datefrom  =  Date ( date ,  { day  =  dayfirst })конецдля  я  =  1 ,  подсчет  делаемесли  не  datefrom,  то  break  end  - превышает лимит датыlist [ i ]  =  datefromdatefrom  =  datefrom  +  7конец список возвратаконец- Таблица для получения текущей даты / времени (UTC), но только при необходимости.local  current  =  setmetatable ({},  {__index  =  функция  ( сам ,  ключ )местный  d  =  os.date ( '! * t' )я . год  =  d . годя . месяц  =  d . месяця . день  =  д . денья . час  =  д . чася . минута  =  d . миня . второй  =  d . секвернуть  rawget ( self ,  key )конец  })локальная  функция  extract_date ( новая дата ,  текст )- Проанализируйте дату / время в тексте и верните n, o где- n = таблица чисел с полями даты / времени- o = таблица опций для AM / PM или AD / BC или формата, если есть- или ничего не вернуть, если известно, что дата недействительна.- Вызывающий абонент определяет, допустимы ли значения в n.- Год должен быть положительным (от «1» до «9999»); используйте "BC" для BC.- В строке ymd год должен состоять из четырех цифр, чтобы избежать двусмысленности.- (от «0001» до «9999»). Единственный способ ввести год <= 0 - указать- дата в виде трех числовых параметров, например ymd Date (-1, 1, 1).- Даты формы д / м / г, м / д / г, г / м / д отклоняются как потенциально неоднозначные.местная  дата ,  options  =  {},  {}если  текст : к югу ( - 1 )  ==  'Z' ,  то- Извлечь дату / время из метки времени Викиданных.- Год может содержать от 1 до 16 цифр, но этот модуль обрабатывает только от 1 до 4 цифр.- Примеры: «+ 2016-06-21T14: 30: 00Z», «-0000000180-00-00T00: 00: 00Z».местный  знак ,  y ,  m ,  d ,  H ,  M ,  S  =  текст : match ( '^ ([+% -]) (% d +)% - (% d% d)% - (% d% d) T ( % d% d): (% d% d): (% d% d) Z $ ' )если  подпиши  тоу  =  ToNumber ( у )если  sign  ==  '-'  и  y  >  0,  тоу  =  - уконецесли  y  <=  0,  товарианты . era  =  'BCE'конецдата . год  =  yм  =  ToNumber ( м )д  =  ToNumber ( д )Н  =  ToNumber ( Н )М  =  ToNumber ( М )S  =  ToNumber ( S )если  m  ==  0,  тоновая дата . partial  =  true дата возврата ,  вариантыконецдата . месяц  =  месли  d  ==  0,  тоновая дата . partial  =  true дата возврата ,  вариантыконецдата . день  =  десли  H  >  0  или  M  >  0  или  S  >  0,  тодата . час  =  Hдата . минута  =  Mдата . второй  =  Sконец дата возврата ,  вариантыконецвозвращатьсяконецлокальная  функция  extract_ymd ( элемент )- Вызывается, когда не установлен ни день, ни месяц.local  y ,  m ,  d  =  item : match ( '^ (% d% d% d% d)% - (% w +)% - (% d% d?) $' )если  у  тогдаесли  дата . год  тогдавозвращатьсяконецесли  m : match ( '^% d% d? $' ),  том  =  ToNumber ( м )ещеm  =  номер_месяца ( м )конецесли  м,  тодата . год  =  ToNumber ( у )дата . месяц  =  мдата . день  =  ToNumber ( д )вернуть  истинуконецконецконецлокальная  функция  extract_day_or_year ( элемент )- Вызывается, когда день будет действительным, или- когда год будет действительным, если год не установлен, а установлен частичный.местный  номер ,  суффикс  =  item : match ( '^ (% d% d?% d?% d?) (. *) $' )если  число,  толокальная  п  =  ToNumber ( число )if  # number  <=  2  и  n  <=  31,  тосуффикс  =  суффикс : нижний ()если  суффикс  ==  ''  или  суффикс  ==  'st'  или  суффикс  ==  'nd'  или  суффикс  ==  'rd'  или  суффикс  ==  'th',  тогдадата . день  =  пвернуть  истинуконецelseif  суффикс  ==  ''  и  newdate . частичное,  а  не  свидание . год  тогдадата . год  =  nвернуть  истинуконецконецконецлокальная  функция  extract_month ( элемент )- месяц должен быть указан как название или аббревиатура; число может быть двусмысленным.местный  m  =  номер_месяца ( элемент )если  м,  тодата . месяц  =  мвернуть  истинуконецконецлокальная  функция  extract_time ( элемент )local  h ,  m ,  s  =  item : match ( '^ (% d% d?): (% d% d) (:?% d *) $' )если  дата . час  или  не  ч  товозвращатьсяконецесли  s  ~ =  '',  тоs  =  s : match ( '^: (% d% d) $' )если  не  S ,  товозвращатьсяконецконецдата . час  =  ToNumber ( ч )дата . минута  = число  тонны ( м )дата . second  =  tonumber ( s )  - ноль, если пустая строкавернуть  истинуконецlocal  item_count  =  0местное  index_timeлокальная  функция  set_ampm ( элемент )местный  H  =  дата . часесли  H  а  не  варианты . am  и  index_time  +  1  ==  item_count,  тогдаварианты . am  =  ampm_options [ item ]  - вызывающий проверил, что это не нольесли  item : match ( '^ [Aa]' ),  тоесли  нет  ( 1  <=  H  и  H  <=  12 ),  товозвращатьсяконецесли  H  ==  12,  тодата . час  =  0конецещеесли  нет  ( 1  <=  H  и  H  <=  23 ),  товозвращатьсяконецесли  H  <=  11,  тодата . час  =  H  +  12конецконецвернуть  истинуконецконецдля  элемента  в  тексте : gsub ( ',' ,  '' ): gsub ( '& nbsp;' ,  '' ): gmatch ( '% S +' )  doitem_count  =  item_count  +  1если  era_text [ элемент ],  то- Эра принимается в своеобразных местах.если  варианты . эра  тогдавозвращатьсяконецварианты . эпоха  =  предметelseif  ampm_options [ элемент ]  тогдаесли  не  set_ampm ( item ),  товозвращатьсяконецelseif  item : find ( ':' ,  1 ,  true )  затемесли  не  extract_time ( элемент ),  товозвращатьсяконецindex_time  =  item_countelseif  дата . день  и  дату . месяц  тогдаесли  дата . год  тогдаreturn  - больше ничего не должно быть, значит, предмет недействителенконецесли  не  item : match ( '^ (% d% d?% d?% d?) $' )  товозвращатьсяконецдата . год  =  ToNumber ( пункт )elseif  дата . день  тогдаесли  не  extract_month ( элемент ),  товозвращатьсяконецelseif  дата . месяц  тогдаесли  не  extract_day_or_year ( элемент ),  товозвращатьсяконецelseif  extract_month ( элемент )  тогдаварианты . format  =  'mdy'elseif  extract_ymd ( элемент )  тогдаварианты . format  =  'ymd'elseif  extract_day_or_year ( элемент )  тогдаесли  дата . день  тогдаварианты . format  =  'dmy'конецещевозвращатьсяконецконецесли  не  дата . год  или  дату . год  ==  0  тогдавозвращатьсяконецместная  эра  =  эра_текст [ параметры . эпоха ]если  эпоха  и  эпоха . isbc  тогдадата . год  =  1  -  дата . годконец дата возврата ,  вариантыконецлокальная  функция  автозаполнения ( date1 ,  дата2 )- Заполните любой пропущенный месяц или день каждой даты, используя- соответствующий компонент с другой даты, если он присутствует,- или с 1, если в обеих датах отсутствует месяц или день.- Это дает хороший результат для расчета разницы- между двумя неполными датами, когда диапазон не нужен.- Возврат заполнен date1, date2 (две полные даты).локальная  функция  заполнена ( a ,  b )- Дата возврата a, если необходимо, с указанием месяца и / или числа с даты b.- Заполненный день усекается, чтобы соответствовать количеству дней в месяце.местный  месяц , день  заполненияесли  не  a . месяц  тогдаfillmonth  =  b . месяц  или  1конецесли  не  . день тогда fillday  =  b . день  или  1конецесли  fillmonth  или  fillday  тогда  - нужно создать новую датуa  =  Дата ( a ,  {month  =  fillmonth ,day  =  math.min ( fillday  или  a . day ,  days_in_month ( a . year ,  fillmonth  или  a . month ,  a . calendar ))})конецвозвращение конецвернуть  заполненный ( DATE1 ,  date2 ),  заполненный ( date2 ,  date1 )конецлокальная  функция  date_add_sub ( LHS ,  RHS ,  is_sub )- Вернуть новую дату из расчета (lhs + rhs) или (lhs - rhs),- или ничего не вернуть, если он недействителен.- Результат равен нулю, если рассчитанная дата превышает допустимые пределы.- Caller гарантирует, что lhs - это дата; его свойства копируются на новую дату.если  lhs . частичный  тогда- Добавление к частичному не поддерживается.- Можно вычесть дату или часть из части, но для этого это не требуется.возвращатьсяконецлокальная  функция  is_prefix ( текст ,  слово ,  минлен )местный  n  =  # текстreturn  ( minlen  или  1 )  <=  n  и  n  <=  # слово  и  текст  ==  word : sub ( 1 ,  n )конецлокальная  функция  do_days ( n )местный  forcetime ,  юлианский деньесли  floor ( n )  ==  n,  тоjd  =  lhs . jdещеforcetime  =  not  lhs . времяjd  =  lhs . jdzконецjd  =  jd  +  ( is_sub  и  - n  или  n )если  forcetime  тогдаJD  =  ToString ( JD )если  не  jd : find ( '.' ,  1 ,  true ),  тоjd  =  jd  ..  '.0'конецконец Дата возврата ( lhs ,  'juliandate' ,  jd )конецесли  type ( rhs )  ==  'number',  то- Добавить / вычесть дни, включая дробные дни.возврат  do_days ( rhs )конецесли  type ( rhs )  ==  'string',  то- правая часть - это один компонент, например «26 месяцев» или «26 месяцев» (с необязательным знаком).- Доли типа «3.25d» принимаются для единиц, которые обрабатываются как дни.локальный  знак ,  numstr ,  id  =  rhs : match ( '^% s * ([+ -]?) ([% d%.] +)% s * (% a +) $' )если  подпиши  тоесли  знак  ==  '-'  тоis_sub  =  not  ( is_sub  и  истина  или  ложь )конецместное  г ,  м ,  днилокальная  Num  =  ToNumber ( NumStr )если  не  число,  товозвращатьсяконецid  =  id : нижний ()если  is_prefix ( id ,  'years' ),  тоy  =  числот  =  0elseif  is_prefix ( id ,  'months' )  тогдаy  =  этаж ( число  /  12 )m  =  число  %  12elseif  is_prefix ( id ,  'weeks' )  тогдадней  =  число  *  7elseif  is_prefix ( id ,  'days' )  тогдадней  =  числоelseif  is_prefix ( id ,  'часы' )  тогдадней  =  число  /  24elseif  is_prefix ( id ,  'minutes' ,  3 ),  тодней  =  число  /  ( 24  *  60 )elseif  is_prefix ( id ,  'секунды' )  тогдадней  =  число  /  ( 24  *  3600 )ещевозвращатьсяконецесли  дни  тоreturn  do_days ( дни )конецесли  numstr : find ( '.' ,  1 ,  true ),  товозвращатьсяконецесли  is_sub,  тоу  =  - ум  =  - мконецassert ( - 11  <=  m  и  m  <=  11 )y  =  lhs . год  +  гм  =  лев . месяц  +  месли  m  >  12,  тоу  =  у  +  1м  =  м  -  12иначе, если  m  <  1,  тоу  =  у  -  1м  =  м  +  12конецместный  г  =  Math.min ( LHS . день ,  Days_in_Month ( у ,  м ,  LHS . календарь )) Дата возврата ( lhs ,  y ,  m ,  d )конецконецесли  is_diff ( rhs ),  томестные  дни  =  прав . age_daysif  ( is_sub  или  false )  ~ =  ( rhs . isnegative  или  false ),  тоdays  =  - дниконецвозврат  lhs  +  днейконецконецlocal  full_date_only  =  {dayabbr  =  правда ,dayname  =  true ,dow  =  true ,dayofweek  =  правда ,dowiso  =  истина ,dayofweekiso  =  правда ,dayofyear  =  правда ,gsd  =  true ,juliandate  =  правда ,jd  =  истина ,jdz  =  истина ,jdnoon  =  правда ,}- Метатаблица для вычисляемых полей даты.local  datemt  =  {__index  =  функция  ( сам ,  ключ )если  rawget ( self ,  'partial' ),  тоесли  full_date_only [ ключ ],  то  вернуть  конецесли  key  ==  'monthabbr'  или  key  ==  'monthdays'  или  key  ==  'monthname',  тогдаесли  не  сам . месяц,  затем  конец возврата конецконецместная  ценностьесли  ключ  ==  'dayabbr',  тогдазначение  =  day_info [ self . доу ] [ 1 ]elseif  key  ==  'dayname'  тогдазначение  =  day_info [ self . доу ] [ 2 ]elseif  key  ==  'dow',  затемзначение  =  ( self . jdnoon  +  1 )  %  7  - день недели 0 = с воскресенья по 6 = сбelseif  key  ==  'dayofweek'  тогдазначение  =  себя . доуelseif  key  ==  'dowiso'  тогдаvalue  =  ( self . jdnoon  %  7 )  +  1  - день недели по ISO 1 = с понедельника по 7 = всelseif  key  ==  'dayofweekiso'  тогдазначение  =  себя . Dowisoelseif  key  ==  'dayofyear'  тогдаlocal  first  =  Дата ( сам . год ,  1 ,  1 ,  сам . календарь ). пнзначение  =  себя . jdnoon  -  первый  +  1  - день года от 1 до 366elseif  key  ==  'era'  тогда- Текст эпохи (никогда не отрицательный) с годом и вариантами.значение  =  get_era_for_year ( сам . параметры . эра ,  сам . год )elseif  key  ==  'format'  затемзначение  =  себя . варианты . формат  или  dmyelseif  key  ==  'gsd'  тогда- GSD = 1 с 00:00:00 до 23:59:59 1 января 1 января нашей эры по григорианскому календарю,- что составляет от 1721425,5 до 1721426,49999.Значение  =  пол ( самостоятельно . JD  -  1721424,5 )elseif  key  ==  'juliandate'  или  key  ==  'jd'  или  key  ==  'jdz',  тогдалокальная  JD ,  JDZ  =  julian_date ( само )rawset ( self ,  'juliandate' ,  jd )rawset ( сам ,  'jd' ,  jd )rawset ( сам ,  'jdz' ,  jdz )возвращение  ключ  ==  «JDZ»  и  JDZ  или  юлианский деньelseif  key  ==  'jdnoon'  тогда- полдень по юлианскому календарю (целое число) календарного дня, когда наступает jd.значение  =  этаж ( self . jd  +  0,5 )elseif  key  ==  'isleapyear'  тогдазначение  =  is_leap_year ( сам . год ,  самостоятельно . календарь )elseif  key  ==  'monthabbr'  тогдазначение  =  month_info [ self . месяц ] [ 1 ]elseif  key  ==  'monthdays',  затемзначение  =  дней_в_месяц ( сам . год ,  сам . месяц ,  сам . календарь )elseif  key  ==  'monthname',  затемзначение  =  month_info [ self . месяц ] [ 2 ]конецесли  значение  ~ =  nil,  тоrawset ( собственный ,  ключ ,  значение )возвращаемое  значениеконецконец ,}- Операторы даты.локальная  функция  mt_date_add ( LHS ,  шк )если  не  is_date ( LHS ) ,  тоlhs ,  rhs  =  rhs ,  lhs  - поставить дату слева (это должна быть дата, чтобы это было вызвано)конецВозвращение  date_add_sub ( LHS ,  шк )конецлокальная  функция  mt_date_sub ( LHS ,  шк )если  is_date ( LHS ) ,  тоесли  is_date ( rhs ),  тоВозвращение  DateDiff ( LHS ,  шк )конецВозвращение  date_add_sub ( LHS ,  шк ,  правда )конецконецлокальная  функция  mt_date_concat ( LHS ,  шк )возвращение  ToString ( LHS )  ..  ToString ( шк )конецлокальная  функция  mt_date_tostring ( self )вернуть  себя : текст ()конецлокальная  функция  mt_date_eq ( LHS ,  шк )- Вернуть истину, если даты идентифицируют одну и ту же дату / время, где, например,- Date (-4712, 1, 1, 'Julian') == Date (-4713, 11, 24, 'Gregorian') верно.- Это вызывается, только если lhs и rhs имеют один и тот же тип и один и тот же метаметод.если  lhs . частичный  или  правый . частичный  тогда- Одно свидание неполное; другой - частичное или полное свидание.- Оба месяца могут быть нулевыми, но должны быть одинаковыми.вернуть  lhs . год  ==  правый . год  и  лев . месяц  ==  прав . месяц  и  lhs . календарь  ==  правый . календарьконецвернуть  lhs . jdz  ==  rhs . jdzконецлокальная  функция  mt_date_lt ( LHS ,  шк )- Вернуть истину, если lhs <rhs, например,- Дата ('1 января 2016') <Дата ('06: 00 1 января 2016 ') верно.- Это вызывается, только если lhs и rhs имеют один и тот же тип и один и тот же метаметод.если  lhs . частичный  или  правый . частичный  тогда- Одно свидание неполное; другой - частичное или полное свидание.если  lhs . календарь  ~ =  прав . календарь  тогдавернуть  lhs . календарь  ==  'юлианский'конецесли  lhs . частичный  тогдаlhs  =  lhs . частичный . первыйконецесли  ОРЗ . частичный  тогдаrhs  =  rhs . частичный . первыйконецконецвернуть  lhs . jdz  <  rhs . jdzконец- [[Примеры синтаксиса для построения даты:Дата (г, м, д, 'julian') календарь по умолчанию - 'грегорианский'Дата (г, м, д, H, M, S, 'julian')Date ('juliandate', jd, 'julian'), если jd содержит "." текстовый вывод включает H: M: SДата ('текущая дата')Дата ('currentdatetime')Date ('1 апреля 1995', 'julian') разобрать дату из текстаDate ('1 апреля 1995 г. н.э.', 'julian') с использованием эры устанавливает флаг, чтобы сделать то же самое для выводаДата ('04: 30: 59 1 апреля 1995 ',' julian ')Дата (дата) копия существующей датыДата (дата, t) такая же, обновлена ​​полями y, m, d, H, M, S из таблицы tDate (t) дата с полями y, m, d, H, M, S из таблицы t]]функция  Date (...)  - для форвардного объявления выше- Вернуть таблицу с датой, предполагая, что всегда применяется единый календарь- (пролептический григорианский календарь или пролептический юлианский календарь), или- ничего не возвращать, если дата недействительна.- Неполная дата имеет действительный год, однако ее месяц может быть нулевым, и- его поля дня и времени равны нулю.- Частичное поле имеет значение false (если полная дата) или таблица (если частичная дата).местные  календари  =  {  julian  =  'Julian' ,  gregorian  =  'Gregorian'  }local  newdate  =  {_id  =  uniq ,calendar  =  'Gregorian' ,  - по умолчанию григорианский календарьhastime  =  false ,  - истина, если ввод устанавливает времяhour  =  0 ,  - всегда устанавливается час / минута / секунда, поэтому не нужно обрабатывать нольминута  =  0 ,второй  =  0 ,options  =  {},list  =  _date_list ,вычитание  =  функция  ( self ,  rhs ,  options )return  DateDiff ( self ,  rhs ,  параметры )конец ,text  =  _date_text ,}местный  тип аргумент ,  datetext ,  is_copy ,  jd_number ,  tnumsместный  numindex  =  0local  numfields  =  {  'год' ,  'месяц' ,  'день' ,  'час' ,  'минута' ,  'секунда'  }местные  номера  =  {}для  _ ,  v  в  ipairs ({...})  сделатьv  =  strip_to_nil ( v )local  vlower  =  type ( v )  ==  'строка'  и  v : lower ()  или  nilесли  v  ==  nil,  то- Игнорировать пустые аргументы после удаления, чтобы модули могли напрямую передавать параметры шаблона.elseif  календари [ vlower ]  тогдановая дата . calendar  =  календари [ vlower ]elseif  vlower  ==  'partial'  тогдановая дата . partial  =  trueelseif  vlower  ==  'fix'  тогдановая дата . want_fix  =  trueElseIf  is_date ( v ) ,  то- Копировать существующую дату (элементы могут быть отменены другими аргументами).если  is_copy  или  tnums,  товозвращатьсяконецis_copy  =  истинановая дата . календарь  =  v . календарьновая дата . частичный  =  v . частичныйновая дата . hastime  =  v . времяновая дата . параметры  =  v . опцииновая дата . год  =  v . годновая дата . месяц  =  v . месяцновая дата . день  =  v . деньновая дата . час  =  v . часновая дата . минута  =  v . минутановая дата . второй  =  v . второйelseif  type ( v )  ==  'table'  тогдаесли  tnums,  товозвращатьсяконецtnums  =  {}local  tfields  =  {  год = 1 ,  месяц = 1 ,  день = 1 ,  час = 2 ,  минута = 2 ,  секунда = 2  }для  tk ,  tv  в  парах ( v )  делатьесли  tfields [ tk ],  тоtnums [ тк ]  =  ToNumber ( тв )конецесли  tfields [ tk ]  ==  2,  тоновая дата . hastime  =  trueконецконецещелокальная  Num  =  ToNumber ( v )если  не  num  и  argtype  ==  'setdate'  и  numindex  ==  1,  точисло  =  номер_месяца ( v )конецесли  число,  тоесли  не  argtype,  тоargtype  =  'установленная дата'конецесли  argtype  ==  'setdate'  и  numindex  <  6,  тогдануминдекс  =  нуминдекс  +  1числа [ numfields [ numindex ]]  =  числоelseif  argtype  ==  'juliandate',  а  не  jd_number,  тогдаjd_number  =  числоесли  type ( v )  ==  'строка',  тоесли  v : find ( '.' ,  1 ,  true ),  тоновая дата . hastime  =  trueконецelseif  num  ~ =  floor ( num )  тогда- Данное значение было числом. Время будет использовано- если дробная часть отлична от нуля.новая дата . hastime  =  trueконецещевозвращатьсяконецelseif  argtype  тогдавозвращатьсяelseif  type ( v )  ==  'строка'  тогдаесли  v  ==  'currentdate'  или  v  ==  'currentdatetime'  или  v  ==  'juliandate',  тогдаargtype  =  vещеargtype  =  'datetext'datetext  =  vконецещевозвращатьсяконецконецконецесли  argtype  ==  'datetext',  тогдаесли  tnums  или  нет  set_date_from_numbers ( newdate ,  extract_date ( newdate ,  datetext )),  товозвращатьсяконецelseif  argtype  ==  'juliandate'  тогдановая дата . частичный  =  нольновая дата . JD  =  jd_numberесли  не  set_date_from_jd ( newdate ),  товозвращатьсяконецelseif  argtype  ==  'currentdate'  или  argtype  ==  'currentdatetime',  тогдановая дата . частичный  =  нольновая дата . год  =  текущий . годновая дата . месяц  =  текущий . месяцновая дата . день  =  текущий . деньесли  argtype  ==  'currentdatetime',  тогдановая дата . час  =  текущий . часновая дата . минута  =  текущая . минутановая дата . второй  =  текущий . второйновая дата . hastime  =  trueконецновая дата . calendar  =  'Gregorian'  - игнорировать любое указанное название календаряelseif  argtype  ==  'setdate',  затемесли  tnums  или  нет  set_date_from_numbers ( newdate ,  numbers ),  товозвращатьсяконециначе, если  нет  ( is_copy  или  tnums ),  товозвращатьсяконецесли  tnums,  тоновая дата . jd  =  nil  - принудительный пересчет в случае, если jd был установлен до изменения tnumsесли  не  set_date_from_numbers ( newdate ,  tnums ),  товозвращатьсяконецконецесли  newdate . частичный  тогдаместный  год  =  новая дата . годместный  месяц  =  новая дата . месяцlocal  first  =  Дата ( год ,  месяц  или  1 ,  1 ,  новая дата . календарь )месяц  =  месяц  или  12local  last  =  Дата ( год ,  месяц ,  days_in_month ( год ,  месяц ),  новая дата . календарь )новая дата . частичный  =  {  первый  =  первый ,  последний  =  последний  }ещеновая дата . partial  =  false  - избегать поиска по индексуконецsetmetatable ( newdate ,  datemt )local  readonly  =  {}local  mt  =  {__index  =  newdate ,__newindex  =  function ( t ,  k ,  v )  error ( 'date.'  ..  tostring ( k )  ..  'только для чтения' ,  2 )  end ,__add  =  mt_date_add ,__sub  =  mt_date_sub ,__concat  =  mt_date_concat ,__tostring  =  mt_date_tostring ,__eq  =  mt_date_eq ,__lt  =  mt_date_lt ,}Возвращение  setmetatable ( только для чтения ,  т )конецлокальная  функция  _diff_age ( дифф ,  код ,  опция )- Вернуть кортеж целых значений из diff, как указано в коде, за исключением того, что- каждое целое число может быть списком из двух целых чисел для сравнения с частичной датой, или- вернуть nil, если код не поддерживается.- Если хотите округлить, наименее значимая единица округляется до ближайшей целой единицы.- На время добавляется дополнительный день.местный  wantround ,  wantduration ,  wantrangeесли  type ( options )  ==  'table',  тоwantround  =  варианты . круглыйwantduration  =  варианты . продолжительностьwantrange  =  варианты . классифицироватьещеwantround  =  вариантыконецесли  не  is_diff ( diff ),  томестный  f  =  wantduration  и  'продолжительность'  или  'возраст'error ( f  ..  ': нужна разница в датах (используйте "diff:'  ..  f  ..  '()" с двоеточием)' ,  2 )конецесли  разн . частичный  тогда- Игнорируйте бессмысленность, желаемую продолжительность.локальная  функция  choose ( v )если  type ( v )  ==  'table',  тоесли  не  wantrange  или  v [ 1 ]  ==  v [ 2 ],  то- Пример: Дата («частично», 2005 г.) - «Дата (« частично », 2001 г.) дает- diff.years = {3, 4}, чтобы показать диапазон возможных результатов.- Если диапазон не нужен, выберите второе значение как более ожидаемое.вернуть  v [ 2 ]конецконецвернуть  vконецесли  code  ==  'ym'  или  code  ==  'ymd',  тогдаесли  не  хотите ранжировать  и  разн . равно нулю  тогда- Это позволяет избежать неожиданного результата, такого как- Дата («частично», 2001 г.) - Дата («частично», 2001 г.)- давая diff = {years = 0, months = {0, 11}}- что будет указано как 0 лет и 11 месяцев.возврат  0 ,  0конецобратный  выбор ( разна . частичные . года ),  выберите ( разна . частичные . месяцы )конецесли  code  ==  'y'  тогдавозврат  выбрать ( разн . част . лет )конецесли  code  ==  'm'  или  code  ==  'w'  или  code  ==  'd',  тогдаВозвращение  выбрать ({  диф . парциальное . mindiff : возраст ( код ),  диф . парциальное . maxdiff : возраст ( код )  })конецвернуть  нольконецместные  extra_days  =  wantduration  и  1  или  0если  code  ==  'wd'  или  code  ==  'w'  или  code  ==  'd',  тогдалокальное  смещение  =  wantround  и  0,5  или  0местные  дни  =  разн . age_days  +  extra_daysесли  code  ==  'wd'  или  code  ==  'd',  тодни  =  этаж ( дни  +  смещение )если  code  ==  'd'  тогда дни возвратаконецвозвратный  этаж ( дней / 7 ),  дней  %  7конецвозвратный  этаж ( дней / 7  +  зачет )конецместный  H ,  M ,  S  =  разн . часов ,  разн . минут ,  разн . секундыесли  code  ==  'dh'  или  code  ==  'dhm'  или  code  ==  'dhms'  или  code  ==  'h'  или  code  ==  'hm'  или  code  ==  'hms'  или  code  ==  'M'  или  code  ==  's'  тогдаместные  дни  =  этаж ( разн . возраст_дней  +  дополнительные_дни )местный  inc_hourесли  хотите,  тоесли  code  ==  'dh'  или  code  ==  'h',  тогдаесли  M  > =  30,  тоinc_hour  =  правдаконецelseif  code  ==  'dhm'  или  code  ==  'hm'  тогдаесли  S  > =  30,  тоМ  =  М  +  1если  M  > =  60,  тоM  =  0inc_hour  =  правдаконецконецelseif  code  ==  'M'  тогдаесли  S  > =  30,  тоМ  =  М  +  1конецеще- Ничего не нужно, потому что S - целое число.конецесли  inc_hour,  тоH  =  H  +  1если  H  > =  24,  тоH  =  0дни  =  дни  +  1конецконецконецесли  code  ==  'dh'  или  code  ==  'dhm'  или  code  ==  'dhms',  тогдаесли  code  ==  'dh'  тогда дней возврата ,  Чelseif  code  ==  'dhm'  тогдавозвратные  дней ,  H ,  Mеще дни возврата ,  H ,  M ,  Sконецконецместные  часы  =  дни  *  24  +  Hесли  code  ==  'h'  тогда часы возвратаelseif  code  ==  'hm'  тогда часы возврата ,  Мelseif  code  ==  'M'  или  code  ==  's'  тогдаM  =  часы  *  60  +  Mесли  code  ==  'M',  тогдавернуть  Mконецвернуть  M  *  60  +  Sконец часы возврата ,  M ,  Sконецесли  хотите,  томестный  inc_hourесли  code  ==  'ymdh'  или  code  ==  'ymwdh'  тогдаесли  M  > =  30,  тоinc_hour  =  правдаконецelseif  code  ==  'ymdhm'  или  code  ==  'ymwdhm'  тогдаесли  S  > =  30,  тоМ  =  М  +  1если  M  > =  60,  тоM  =  0inc_hour  =  правдаконецконецelseif  code  ==  'ymd'  или  code  ==  'ymwd'  или  code  ==  'yd'  или  code  ==  'md'  тогдаесли  H  > =  12,  тоextra_days  =  extra_days  +  1конецконецесли  inc_hour,  тоH  =  H  +  1если  H  > =  24,  тоH  =  0extra_days  =  extra_days  +  1конецконецконецлокальный  y ,  m ,  d  =  diff . лет ,  разн . месяцев ,  разн . днейесли  extra_days  >  0,  тоd  =  d  +  extra_daysесли  d  >  28  или  code  ==  'yd',  тогда- Пересчитать, если прошел месяц.разн  =  разн . date1  +  extra_days  -  разн . date2y ,  m ,  d  =  разн . лет ,  разн . месяцев ,  разн . днейконецконецесли  code  ==  'ymd'  тогдавозврат  y ,  m ,  delseif  code  ==  'yd'  тогдаесли  y  >  0,  то- Известно, что diff.date1> diff.date2.разн  =  разн . date1  -  ( разн . date2  +  ( у  ..  'у' ))конецвозвращение  у ,  пол ( разн . age_days )elseif  code  ==  'md'  тогдавозврат  y  *  12  +  m ,  delseif  code  ==  'ym'  или  code  ==  'm'  тогдаесли  хотите,  тоесли  d  > =  16,  том  =  м  +  1если  m  > =  12,  тот  =  0у  =  у  +  1конецконецконецесли  code  ==  'ym'  тогдавозврат  г ,  мконецвозврат  y  *  12  +  melseif  code  ==  'ymw'  тогдаместные  недели  =  этаж ( д / 7 )если  хотите,  томестные  дни  =  d  %  7если  дней  >  3  или  ( дней  ==  3  и  H  > =  12 ),  тонедели  =  недели  +  1конецконецвозврат  г ,  м ,  неделиelseif  code  ==  'ymwd'  тогдадоходность  г ,  м ,  этаж ( д / 7 ),  д  %  7elseif  code  ==  'ymdh'  тогдавозврат  y ,  m ,  d ,  Helseif  code  ==  'ymwdh'  тогдадоходность  y ,  м ,  этаж ( д / 7 ),  д  %  7 ,  Helseif  code  ==  'ymdhm'  тогдавозврат  y ,  m ,  d ,  H ,  Melseif  code  ==  'ymwdhm'  тогдадоходность  y ,  м ,  этаж ( д / 7 ),  д  %  7 ,  H ,  Mконецесли  code  ==  'y'  тогдаесли  wantround  и  m  > =  6,  тоу  =  у  +  1конецвернуть  yконецвернуть  нольконецлокальная  функция  _diff_duration ( дифф ,  код ,  опция )если  type ( options )  ~ =  'table',  тоoptions  =  {  round  =  options  }конецварианты . продолжительность  =  правдаВозвращение  _diff_age ( дифф ,  код ,  опция )конец- Метатаблица для некоторых операций с разницей в датах.diffmt  =  {  - для предварительного объявления выше__concat  =  функция  ( LHS ,  шк )возвращение  ToString ( LHS )  ..  ToString ( шк )конец ,__tostring  =  функция  ( сам )вернуться в  строку ( self . age_days )конец ,__index  =  функция  ( сам ,  ключ )местная  ценностьесли  ключ  ==  'age_days',  тоесли  rawget ( self ,  'partial' ),  толокальная  функция  jdz ( дата )возврат  ( дата . частичная  и  дата . частичная . первая  или  дата ). jdzконецзначение  =  jdz ( self . date1 )  -  jdz ( self . date2 )ещезначение  =  себя . дата1 . jdz  -  сам . дата2 . jdzконецконецесли  значение  ~ =  nil,  тоrawset ( собственный ,  ключ ,  значение )возвращаемое  значениеконецконец ,}Функция  DateDiff ( DATE1 ,  date2 ,  варианты )  - для прямой декларации выше- Вернуть таблицу с разницей между двумя датами (date1 - date2).- Разница отрицательная, если date1 старше date2.- Ничего не возвращать, если недействителен.- Если d = date1 - date2, то- date1 = date2 + d- Если date1> = date2 и в датах не указано время H: M: S, тогда- date1 = date2 + (d.years .. 'y') + (d.months .. 'm') + d.days- где сначала добавляются большие единицы времени.- Результат Date (2015,1, x) + '1m' равен Date (2015,2,28) для- x = 28, 29, 30, 31. Это означает, например,- d = Дата (2015,3,3) - Дата (2015,1,31)- дает d.years, d.months, d.days = 0, 1, 3 (исключая date1).если  не  ( is_date ( date1 )  и  is_date ( дата2 )  и  date1 . календарь  ==  дата2 . календарь ) ,  товозвращатьсяконецместные  нуждыесли  type ( options )  ==  'table',  тоwantfill  =  options . наполнятьконецlocal  isnegative  =  ложьместный  iszero  =  falseесли  date1  <  date2  затемisnegative  =  правдаdate1 ,  дата2  =  дата2 ,  date1ElseIf  date1  ==  date2  затемiszero  =  trueконец- Известно, что date1> = date2 (период от date2 до date1).если  date1 . частичное  или  дата2 . частичный  тогда- Две частичные даты могут иметь временные рамки:--------------------- A ================= B --- date1 от A до B включительно-------- C ======= D -------------------------- date2 от C до D включительно- date1> date2 iff A> C (date1.partial.first> date2.partial.first)- Периоды могут перекрываться («апрель 2001» - «2001»):------------- A === B ------------------------- A = 2001-04-01 B = 2001-04-30-------- C ===================== D ------------ C = 2001-01-01 D = 31 декабря 2001 г.если  хотите,  то заполнитеdate1 ,  дата2  =  автозаполнение ( date1 ,  дата2 )ещелокальная  функция  zdiff ( date1 ,  дата2 )локальная  дифф  =  date1  -  date2если  разн . тогда отрицательно return  date1  -  date1  - действительный diff в случае, если мы вызываем его методыконецвернуть  разницуконецлокальная  функция  getdate ( дата ,  которая ) дата возврата . частичная  и  дата . частичный [ который ]  или  датаконецлокальная  maxdiff  =  zdiff ( GETDATE ( date1 ,  'последний' ),  GETDATE ( date2 ,  'первый' ))локальная  mindiff  =  zdiff ( GETDATE ( date1 ,  'первый' ),  GETDATE ( date2 ,  'последний' ))местные  годы ,  месяцыесли  maxdiff . лет  ==  миндифф . лет  тогдалет  =  максдифф . годыесли  maxdiff . месяцев  ==  mindiff . месяцев  тогдамесяцев  =  maxdiff . месяцыещемесяцев  =  {  mindiff . месяцев ,  maxdiff . месяцев  }конецещелет  =  {  mindiff . лет ,  maxdiff . лет  }конецreturn  setmetatable ({date1  =  date1 ,дата2  =  дата2 ,partial  =  {годы  =  годы ,месяцы  =  месяцы ,максдифф  =  максдифф ,mindiff  =  mindiff ,},isnegative  =  isnegative ,iszero  =  iszero ,возраст  =  _diff_age ,duration  =  _diff_duration ,},  diffmt )конецконецлокальный  y1 ,  m1  =  date1 . год ,  дата1 . месяцлокальный  y2 ,  m2  =  date2 . год ,  дата2 . месяцместные  годы  =  y1  -  y2местные  месяцы  =  m1  -  m2местный  d1  =  date1 . день  +  hms ( date1 )местный  d2  =  date2 . день  +  HMS ( date2 )местные  дни ,  времяесли  d1  > =  d2,  тодней  =  d1  -  d2ещемесяцы  =  месяцы  -  1- Получить дни в предыдущем месяце (до даты «до»), поскольку в декабре 31 день.local  dpm  =  m1  >  1  и  days_in_month ( y1 ,  m1  -  1 ,  date1 . calendar )  или  31если  d2  > =  dpm,  тодней  =  d1  -  HMS ( date2 )ещедни  =  dpm  -  d2  +  d1конецконецесли  месяцев  <  0,  толет  =  лет  -  1месяцев  =  месяцев  +  12конецdays ,  time  =  math.modf ( дни )местное  H ,  M ,  S  =  h_m_s ( время )return  setmetatable ({date1  =  date1 ,дата2  =  дата2 ,partial  =  false ,  - избегать поиска по индексугоды  =  годы ,месяцы  =  месяцы ,days  =  дни ,часы  =  H ,минут  =  M ,секунды  =  S ,isnegative  =  isnegative ,iszero  =  iszero ,возраст  =  _diff_age ,duration  =  _diff_duration ,},  diffmt )конецreturn  {_current  =  ток ,_Date  =  Дата ,_days_in_month  =  days_in_month ,}