lubridate/0000755000176200001440000000000013263357253012236 5ustar liggesuserslubridate/po/0000755000176200001440000000000013103077700012641 5ustar liggesuserslubridate/po/R-lubridate.pot0000644000176200001440000001021313103077700015534 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: R 2.15.1\n" "Report-Msgid-Bugs-To: bugs@r-project.org\n" "POT-Creation-Date: 2013-03-29 14:39\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" msgid "estimate only: convert periods to intervals for accuracy" msgstr "" msgid "estimate only: convert difftimes to intervals for accuracy" msgstr "" msgid "estimate only: convert durations to intervals for accuracy" msgstr "" msgid "cannot map durations to months" msgstr "" msgid "coercing interval to duration" msgstr "" msgid "date(s) not in POSIXt or Date format" msgstr "" msgid "Unknown formats supplied:" msgstr "" msgid "," msgstr "" msgid "by is not a recognized timespan object" msgstr "" msgid "an interval cannot be shifted by another interval. \n\t\tConvert second interval to a period or duration." msgstr "" msgid "Union includes intervening time between intervals." msgstr "" msgid "Cases" msgstr "" msgid "result in discontinuous intervals." msgstr "" msgid "Argument 1 is not a recognized date-time" msgstr "" msgid "unrecognized date format" msgstr "" msgid "+ undefined for Interval class:\n manipulate with int_start(), int_end() and int_shift()\n or change class with as.duration()" msgstr "" msgid "Incompatible timespan classes:\n change class with as.duration() or as.period()" msgstr "" msgid "+ undefined for Interval class:\nConsider intersect(), union(), or setdiff()\nor change class with as.period() or as.duration()" msgstr "" msgid "+ undefined for Interval class:\n manipulate with int_start(), int_end() and int_shift()\n or change class with as.period()" msgstr "" msgid "+ undefined for Interval class:\n manipulate with int_start(), int_end() and int_shift()\n or change class with as.duration() or as.period()" msgstr "" msgid "Remainder cannot be expressed as fraction of a period.\n Performing %/%." msgstr "" msgid "estimate only: convert to intervals for accuracy" msgstr "" msgid "Incompatible timespan classes:\n change class with as.duration() or put interval in numerator." msgstr "" msgid "interval / interval not defined" msgstr "" msgid "Incompatible timespan classes:\n change class with as.period() or put interval in numerator." msgstr "" msgid "Cannot divide numeric by duration" msgstr "" msgid "Cannot divide numeric by interval" msgstr "" msgid "Cannot divide numeric by period" msgstr "" msgid "%% not defined for Interval class\nConsider setdiff()" msgstr "" msgid "%m+% only handles Period objects with month or year units" msgstr "" msgid "%m-% only handles Period objects with month or year units" msgstr "" msgid "%m+% only handles month and years. Add other periods separately with '+'" msgstr "" msgid "cannot multiply time span by time span" msgstr "" msgid "interval does not align: coercing to duration" msgstr "" msgid "- undefined for Interval class:\nConsider intersect(), union(), or setdiff()\nor change class with as.period() or as.duration()" msgstr "" msgid "- undefined for Interval class:\n manipulate with int_start(), int_end() and int_shift()\n or change class with as.duration() or as.period()" msgstr "" msgid "No formats could be infered from the training set." msgstr "" msgid "failed to parse." msgstr "" msgid "parsed with" msgstr "" msgid "^@|@$" msgstr "" msgid "Internal function parse_date has been removed from lubridate package. Plese use parse_date_time instead." msgstr "" msgid "arguments must have same length" msgstr "" msgid "cannot compare Period to Duration:\ncoerce with as.duration" msgstr "" msgid "cannot compare Period to numeric:\ncoerce with as.numeric" msgstr "" msgid "Couldn't guess formats of:" msgstr "" msgid "Multiple formats matched:" msgstr "" msgid "\"" msgstr "" msgid "\"(" msgstr "" msgid ")" msgstr "" msgid "Using: \"" msgstr "" msgid "conflicting days input" msgstr "" msgid "longer object length is not a multiple of shorter object length" msgstr "" msgid "Invalid unit name:" msgstr "" msgid "Invalid difftime name:" msgstr "" msgid "Invalid period name:" msgstr "" lubridate/po/R-it.po0000644000176200001440000001273513103077700014024 0ustar liggesusersmsgid "" msgstr "" "Project-Id-Version: R 2.15.1\n" "Report-Msgid-Bugs-To: bugs@r-project.org\n" "POT-Creation-Date: 2013-03-29 14:39\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: dmedri@gmail.com \n" "Language-Team: Italian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" msgid "estimate only: convert periods to intervals for accuracy" msgstr "stima solamente: converte i periodi in intervalli per accuratezza" msgid "estimate only: convert difftimes to intervals for accuracy" msgstr "stima solamente: converte le differente di tempo in intervalli per accuratezza" msgid "estimate only: convert durations to intervals for accuracy" msgstr "stima solamente: converte le durate in intervalli per accuratezza" msgid "cannot map durations to months" msgstr "non è possibile mappare la durata in mesi" msgid "coercing interval to duration" msgstr "conversione degli intervalli in durate" msgid "date(s) not in POSIXt or Date format" msgstr "date in formato differente da POSIXt o Date" msgid "Unknown formats supplied:" msgstr "Indicati formati sconosciuti:" msgid "," msgstr "," msgid "by is not a recognized timespan object" msgstr "" msgid "an interval cannot be shifted by another interval. \n\t\tConvert second interval to a period or duration." msgstr "" msgid "Union includes intervening time between intervals." msgstr "" msgid "Cases" msgstr "Casi" msgid "result in discontinuous intervals." msgstr "risultato in intervalli discontinui." msgid "Argument 1 is not a recognized date-time" msgstr "L'argomento 1 non è riconosciuto come date-time" msgid "unrecognized date format" msgstr "formato data non riconosciuto" msgid "+ undefined for Interval class:\n manipulate with int_start(), int_end() and int_shift()\n or change class with as.duration()" msgstr "" msgid "Incompatible timespan classes:\n change class with as.duration() or as.period()" msgstr "" msgid "+ undefined for Interval class:\nConsider intersect(), union(), or setdiff()\nor change class with as.period() or as.duration()" msgstr "" msgid "+ undefined for Interval class:\n manipulate with int_start(), int_end() and int_shift()\n or change class with as.period()" msgstr "" msgid "+ undefined for Interval class:\n manipulate with int_start(), int_end() and int_shift()\n or change class with as.duration() or as.period()" msgstr "" msgid "Remainder cannot be expressed as fraction of a period.\n Performing %/%." msgstr "" msgid "estimate only: convert to intervals for accuracy" msgstr "stima solamente: converte in intervalli per accuratezza" msgid "Incompatible timespan classes:\n change class with as.duration() or put interval in numerator." msgstr "" msgid "interval / interval not defined" msgstr "intervallo / intervallo non definito" msgid "Incompatible timespan classes:\n change class with as.period() or put interval in numerator." msgstr "" msgid "Cannot divide numeric by duration" msgstr "Non è possibile dividere un tipo numeric per uno duration" msgid "Cannot divide numeric by interval" msgstr "Non è possibile dividere un tipo numeric per uno interval" msgid "Cannot divide numeric by period" msgstr "Non è possibile dividere un tipo numeric per uno period" msgid "%% not defined for Interval class\nConsider setdiff()" msgstr "" msgid "%m+% only handles Period objects with month or year units" msgstr "" msgid "%m-% only handles Period objects with month or year units" msgstr "" msgid "%m+% only handles month and years. Add other periods separately with '+'" msgstr "" msgid "cannot multiply time span by time span" msgstr "" msgid "interval does not align: coercing to duration" msgstr "" msgid "- undefined for Interval class:\nConsider intersect(), union(), or setdiff()\nor change class with as.period() or as.duration()" msgstr "" msgid "- undefined for Interval class:\n manipulate with int_start(), int_end() and int_shift()\n or change class with as.duration() or as.period()" msgstr "" msgid "No formats could be infered from the training set." msgstr "Nessun formato può essere identificato dal training set." msgid "failed to parse." msgstr "analisi non possibile." msgid "parsed with" msgstr "analizzato con" msgid "^@|@$" msgstr "^@|@" msgid "Internal function parse_date has been removed from lubridate package. Plese use parse_date_time instead." msgstr "La funzione interna parse_date è stata rimossa dal pacchetto lubridate. Per piacere, usa parse_date_time al suo posto." msgid "arguments must have same length" msgstr "gli argomenti devono avere la stessa lunghezza" msgid "cannot compare Period to Duration:\ncoerce with as.duration" msgstr "non è possibile comparare i periodi con valori di durata:\nconverti con as.duration" msgid "cannot compare Period to numeric:\ncoerce with as.numeric" msgstr "non è possibile comparare i periodi con valori numerici:\nconverti with as.numeric" msgid "Couldn't guess formats of:" msgstr "Non è possibile rilevare il formato di:" msgid "Multiple formats matched:" msgstr "Confronto formati multipli:" msgid "\"" msgstr "\"" msgid "\"(" msgstr "\"(" msgid ")" msgstr ")" msgid "Using: \"" msgstr "Utilizzo: \"" msgid "conflicting days input" msgstr "inseriti giorni in conflitto" msgid "longer object length is not a multiple of shorter object length" msgstr "" msgid "Invalid unit name:" msgstr "Nome unità non valido:" msgid "Invalid difftime name:" msgstr "Nome difftime non valido:" msgid "Invalid period name:" msgstr "Nome periodo non valido:" lubridate/po/R-ko.po0000644000176200001440000002202713103077700014014 0ustar liggesusers# Korean translation for R lubridate package # /po/R-ko.po # This file is distributed under the same license as the R lubridate package. # R Development Translation Team - Korean # Chel Hee Lee , 2013. # Chel Hee Lee , 2013. # msgid "" msgstr "" "Project-Id-Version: lubridate 1.2.1\n" "Report-Msgid-Bugs-To: bugs@r-project.org\n" "POT-Creation-Date: 2013-03-29 14:35\n" "PO-Revision-Date: 2013-04-01 16:55+0900\n" "Last-Translator: Eugene Jung \n" "Language-Team: R Development Translation Teams (Korean) \n" "Language: ko\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" "X-Poedit-SourceCharset: utf-8\n" "X-Generator: Poedit 1.5.5\n" msgid "estimate only: convert periods to intervals for accuracy" msgstr "추정만: 정확성을 위해 기간(periods)을 간격(intervals)으로 변환" msgid "estimate only: convert difftimes to intervals for accuracy" msgstr "추정만: 정확성을 위해 difftimes를 간격(intervals)으로 변환" msgid "estimate only: convert durations to intervals for accuracy" msgstr "추정만: 정확성을 위해 듀레이션(durations)를 간격(intervals)로 변환함" msgid "cannot map durations to months" msgstr "듀레이션(durations)을 월(months)로 나타낼 수 없습니다." msgid "coercing interval to duration" msgstr "간격(interval)을 듀레이션(duration)으로 강제변환" msgid "date(s) not in POSIXt or Date format" msgstr "날짜가 POSIXt 또는 Date 형태(format)와 일치하지 않습니다." msgid "Unknown formats supplied:" msgstr "알 수 없는 형태(formats)가 입력되었습니다." msgid "," msgstr "," msgid "by is not a recognized timespan object" msgstr "알려진 timespan 객체에 의한 것이 아닙니다." msgid "" "an interval cannot be shifted by another interval. \n" "\t\tConvert second interval to a period or duration." msgstr "" "특정 간격(interval)이 다른 간격(interval)으로 전환될 수 없습니다. \n" "\t\t두 번째 간격(interval)을 일정 기간(period)이나 듀레이션(duration)으로 변" "환합니다." msgid "Union includes intervening time between intervals." msgstr "유니온(union)은 간격간 변환시간을 포함합니다." msgid "Cases" msgstr "사례(cases)" msgid "result in discontinuous intervals." msgstr "이산기간의 결과" msgid "Argument 1 is not a recognized date-time" msgstr "인수 1은 date-time으로 인식되지 않습니다." msgid "unrecognized date format" msgstr "인식되지 않는 날짜 형식" msgid "" "+ undefined for Interval class:\n" " manipulate with int_start(), int_end() and int_shift()\n" " or change class with as.duration()" msgstr "" "+ 정의되지 않은 간격 클래스(interval class)\"\n" " int_start(), int_end(), 그리고 int_shift()로 조정하십시오.\n" " 또는 as.duration()으로 클래스(class)를 변경하십시오." msgid "" "Incompatible timespan classes:\n" " change class with as.duration() or as.period()" msgstr "" "호환되지 않는 기간 클래스(timespan class):\n" " as.duration()이나 as.period()로 클래스를 변경하십시오." msgid "" "+ undefined for Interval class:\n" "Consider intersect(), union(), or setdiff()\n" "or change class with as.period() or as.duration()" msgstr "" "+ 간격 클래스(interval class)가 정의되지 않음:\n" "intersect(), union() 또는 setfiff()를 고려해 보십시오\n" "또는 as.period()나 as.duration()으로 클래스를 변경하십시오." msgid "" "+ undefined for Interval class:\n" " manipulate with int_start(), int_end() and int_shift()\n" " or change class with as.period()" msgstr "" "+ 간격 클래스(interval class)가 정의되지 않음:\n" "int_start(), int_end(), 그리고 int_shift()로 조정하십시오\n" "또는 as.period()로 클래스를 변경하십시오." msgid "" "+ undefined for Interval class:\n" " manipulate with int_start(), int_end() and int_shift()\n" " or change class with as.duration() or as.period()" msgstr "" "간격 클래스(interval class)가 정의되지 않음:\n" "int_start(), int_end(), 그리고 int_shift()로 조정하십시오.\n" "또는 as.duration()이나 as.period()으로 클래스를 변경하십시오." msgid "" "Remainder cannot be expressed as fraction of a period.\n" " Performing %/%." msgstr "" "나머지는 기간의 일부로 표현될 수 없습니다.\n" "진행률 %/%" msgid "estimate only: convert to intervals for accuracy" msgstr "추정만: 정확성을 위해 간격(intervals)로 변환" msgid "" "Incompatible timespan classes:\n" " change class with as.duration() or put interval in numerator." msgstr "" "호환되지 않는 기간 클래스(timespan class):\n" "as.duration()으로 클래스를 변경하거나 분자에 간격 삽입하십시오." msgid "interval / interval not defined" msgstr "간격/정의되지 않은 간격" msgid "" "Incompatible timespan classes:\n" " change class with as.period() or put interval in numerator." msgstr "" "호환되지 않는 기간 클래스(timespan class):\n" "as.period()로 클래스를 변경하거나 분자에 간격을 삽입하십시오." msgid "Cannot divide numeric by duration" msgstr "듀레이션에 의해 숫자로 나누어지지 않습니다." msgid "Cannot divide numeric by interval" msgstr "간격에 의해 숫자로 나누어지지 않습니다." msgid "Cannot divide numeric by period" msgstr "간격에 의해 숫자로 나누어지지 않습니다." msgid "" "%% not defined for Interval class\n" "Consider setdiff()" msgstr "" "%% 간격 클래스(interval class)로 정의되지 않음\n" "setdiff()를 고려하십시오." msgid "%m+% only handles Period objects with month or year units" msgstr "" "%m+%만 오로지 월(month) 또는 년(year) 단위로 기간 객체(period objects)를 다룹" "니다." msgid "%m-% only handles Period objects with month or year units" msgstr "" "%m-%만 오로지 월(month) 또는 년(year) 단위로 기간 객체(period objects)를 다룹" "니다." msgid "" "%m+% only handles month and years. Add other periods separately with '+'" msgstr "" "%m+%만 오로지 월(month) 또는 년(year)을 다룹니다. 다른 기간은 별도로 \"+\"에 " "의해 추가하십시오." msgid "cannot multiply time span by time span" msgstr "기간을 기간으로 곱할 수 없습니다." msgid "interval does not align: coercing to duration" msgstr "간격이 정렬되지 않습니다: 듀레이션으로 강제변환합니다." msgid "" "- undefined for Interval class:\n" "Consider intersect(), union(), or setdiff()\n" "or change class with as.period() or as.duration()" msgstr "" "정의되지 않은 간격 클래스(interval class):\n" "intersect(), union(), 또는 setdiff()를 고려해 보십시오\n" "또는 as.period()나 as.duration()으로 클래스를 변경하십시오." msgid "" "- undefined for Interval class:\n" " manipulate with int_start(), int_end() and int_shift()\n" " or change class with as.duration() or as.period()" msgstr "" "정의되지 않은 간격 클래스(interval class):\n" "int_start(), int_end() 그리고 int_shift()로 조정해 보십시오\n" "또는 as.duration()이나 as.period()로 클래스를 변경하십시오." msgid "No formats could be infered from the training set." msgstr "실험집단(traininig set)으로 부터 추정할 수 없는 형식(format)" msgid "failed to parse." msgstr "parse 실패" msgid "parsed with" msgstr "다음으로 parse" msgid "^@|@$" msgstr "^@|@$" msgid "" "Internal function parse_date has been removed from lubridate package. Plese " "use parse_date_time instead." msgstr "" "내부 함수 parse_date가 lubridate 패키지에서 제거되었습니다. 대신에 " "parse_date_time을 사용해 주십시오." msgid "arguments must have same length" msgstr "인수(arguments)는 같은 길이를 가져야 합니다." msgid "" "cannot compare Period to Duration:\n" "coerce with as.duration" msgstr "" "기간(period)과 듀레이션(duration)을 비교할 수 없습니다.:\n" "as.duration으로 강제변환합니다." msgid "" "cannot compare Period to numeric:\n" "coerce with as.numeric" msgstr "" "기간(period)과 숫자(numeric)을 비교할 수 없습니다.:\n" "as.numeric으로 강제변환합니다." msgid "Couldn't guess formats of:" msgstr "Quess 할 수 없는 형식(format)입니다." msgid "Multiple formats matched:" msgstr "여러 개의 형식(formats)이 대응되었습니다." msgid "\"" msgstr "\"" msgid "\"(" msgstr "\"(" msgid ")" msgstr ")" msgid "Using: \"" msgstr "\"을 사용하십시오." msgid "conflicting days input" msgstr "날짜 입력이 충돌합니다." msgid "longer object length is not a multiple of shorter object length" msgstr "보다 긴 객체 길이가 보다 짧은 객체 길이의 배수는 아닙니다." msgid "Invalid unit name:" msgstr "유효하지 않은 단위(unit) 이름입니다:" msgid "Invalid difftime name:" msgstr "유효하지 않은 difftime 이름입니다:" msgid "Invalid period name:" msgstr "유효하지 않은 기간(period) 이름입니다:" lubridate/inst/0000755000176200001440000000000013263152652013207 5ustar liggesuserslubridate/inst/CITATION0000644000176200001440000000126013102102352014323 0ustar liggesuserscitHeader("To cite lubridate in publications use:") citEntry(entry = "Article", title = "Dates and Times Made Easy with {lubridate}", author = personList(as.person("Garrett Grolemund"), as.person("Hadley Wickham")), journal = "Journal of Statistical Software", year = "2011", volume = "40", number = "3", pages = "1--25", url = "http://www.jstatsoft.org/v40/i03/", textVersion = paste("Garrett Grolemund, Hadley Wickham (2011).", "Dates and Times Made Easy with lubridate.", "Journal of Statistical Software, 40(3), 1-25.", "URL http://www.jstatsoft.org/v40/i03/.") ) lubridate/inst/cctz.sh0000644000176200001440000000056313201152061014474 0ustar liggesusers#!/bin/bash cctz=../src/cctz/ rm -rf $cctz mkdir $cctz git clone https://github.com/google/cctz.git cctz_tmp cp -r cctz_tmp/include $cctz/include LIBCCTZ="tzfile time_zone_fixed time_zone_if time_zone_impl time_zone_info time_zone_libc time_zone_lookup time_zone_posix" mkdir $cctz/src/ for f in $LIBCCTZ do cp ./cctz_tmp/src/$f* $cctz/src/ done rm -rf cctz_tmp lubridate/inst/pkgdown/0000755000176200001440000000000013234630403014651 5ustar liggesuserslubridate/inst/pkgdown/assets/0000755000176200001440000000000013234630403016153 5ustar liggesuserslubridate/inst/pkgdown/assets/tidyverse.css.map0000644000176200001440000027041113234630403021464 0ustar liggesusers{ "version": 3, "mappings": "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", "sources": ["../../../../../tmp/tidytemplate/scss/_bootstrap.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_normalize.scss","../../../../../tmp/tidytemplate/scss/_bootswatch.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_print.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_glyphicons.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_scaffolding.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_vendor-prefixes.scss","../../../../../tmp/tidytemplate/scss/_variables.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_tab-focus.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_image.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_type.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_text-emphasis.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_background-variant.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_clearfix.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_text-overflow.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_code.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_grid.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_grid.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_grid-framework.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_tables.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_table-row.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_forms.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_forms.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_buttons.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_buttons.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_opacity.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_component-animations.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_dropdowns.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_nav-divider.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_reset-filter.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_button-groups.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_border-radius.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_input-groups.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_navs.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_navbar.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_nav-vertical-align.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_breadcrumbs.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_pagination.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_pagination.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_pager.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_labels.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_labels.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_badges.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_jumbotron.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_thumbnails.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_alerts.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_alerts.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_progress-bars.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_gradients.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_progress-bar.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_media.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_list-group.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_list-group.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_panels.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_panels.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_responsive-embed.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_wells.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_close.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_modals.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_tooltip.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_reset-text.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_popovers.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_carousel.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_utilities.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_center-block.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_hide-text.scss","../../../../../tmp/tidytemplate/scss/bootstrap/_responsive-utilities.scss","../../../../../tmp/tidytemplate/scss/bootstrap/mixins/_responsive-visibility.scss"], "names": [], "file": "tidyverse.css" } lubridate/inst/pkgdown/assets/tidyverse.css0000644000176200001440000052650013234630403020713 0ustar liggesusers@charset "UTF-8"; /*! * Bootstrap v3.3.7 (http://getbootstrap.com) * Copyright 2011-2016 Twitter, Inc. * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) */ /*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ @import url("https://fonts.googleapis.com/css?family=Source+Code+Pro:300,400,700|Source+Sans+Pro:300,400,700"); html { font-family: sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; } body { margin: 0; } article, aside, details, figcaption, figure, footer, header, hgroup, main, menu, nav, section, summary { display: block; } audio, canvas, progress, video { display: inline-block; vertical-align: baseline; } audio:not([controls]) { display: none; height: 0; } [hidden], template { display: none; } a { background-color: transparent; } a:active, a:hover { outline: 0; } abbr[title] { border-bottom: 1px dotted; } b, strong { font-weight: bold; } dfn { font-style: italic; } h1 { font-size: 2em; margin: 0.67em 0; } mark { background: #ff0; color: #000; } small { font-size: 80%; } sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } sup { top: -0.5em; } sub { bottom: -0.25em; } img { border: 0; } svg:not(:root) { overflow: hidden; } figure { margin: 1em 40px; } hr { box-sizing: content-box; height: 0; } pre { overflow: auto; } code, kbd, pre, samp { font-family: monospace, monospace; font-size: 1em; } button, input, optgroup, select, textarea { color: inherit; font: inherit; margin: 0; } button { overflow: visible; } button, select { text-transform: none; } button, html input[type="button"], input[type="reset"], input[type="submit"] { -webkit-appearance: button; cursor: pointer; } button[disabled], html input[disabled] { cursor: default; } button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; } input { line-height: normal; } input[type="checkbox"], input[type="radio"] { box-sizing: border-box; padding: 0; } input[type="number"]::-webkit-inner-spin-button, input[type="number"]::-webkit-outer-spin-button { height: auto; } input[type="search"] { -webkit-appearance: textfield; box-sizing: content-box; } input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; } fieldset { border: 1px solid #c0c0c0; margin: 0 2px; padding: 0.35em 0.625em 0.75em; } legend { border: 0; padding: 0; } textarea { overflow: auto; } optgroup { font-weight: bold; } table { border-collapse: collapse; border-spacing: 0; } td, th { padding: 0; } /*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */ @media print { *, *:before, *:after { background: transparent !important; color: #000 !important; box-shadow: none !important; text-shadow: none !important; } a, a:visited { text-decoration: underline; } a[href]:after { content: " (" attr(href) ")"; } abbr[title]:after { content: " (" attr(title) ")"; } a[href^="#"]:after, a[href^="javascript:"]:after { content: ""; } pre, blockquote { border: 1px solid #999; page-break-inside: avoid; } thead { display: table-header-group; } tr, img { page-break-inside: avoid; } img { max-width: 100% !important; } p, h2, h3 { orphans: 3; widows: 3; } h2, h3 { page-break-after: avoid; } .navbar { display: none; } .btn > .caret, .dropup > .btn > .caret { border-top-color: #000 !important; } .label { border: 1px solid #000; } .table { border-collapse: collapse !important; } .table td, .table th { background-color: #fff !important; } .table-bordered th, .table-bordered td { border: 1px solid #ddd !important; } } @font-face { font-family: 'Glyphicons Halflings'; src: url("../fonts/bootstrap/glyphicons-halflings-regular.eot"); src: url("../fonts/bootstrap/glyphicons-halflings-regular.eot?#iefix") format("embedded-opentype"), url("../fonts/bootstrap/glyphicons-halflings-regular.woff2") format("woff2"), url("../fonts/bootstrap/glyphicons-halflings-regular.woff") format("woff"), url("../fonts/bootstrap/glyphicons-halflings-regular.ttf") format("truetype"), url("../fonts/bootstrap/glyphicons-halflings-regular.svg#glyphicons_halflingsregular") format("svg"); } .glyphicon { position: relative; top: 1px; display: inline-block; font-family: 'Glyphicons Halflings'; font-style: normal; font-weight: normal; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .glyphicon-asterisk:before { content: "\002a"; } .glyphicon-plus:before { content: "\002b"; } .glyphicon-euro:before, .glyphicon-eur:before { content: "\20ac"; } .glyphicon-minus:before { content: "\2212"; } .glyphicon-cloud:before { content: "\2601"; } .glyphicon-envelope:before { content: "\2709"; } .glyphicon-pencil:before { content: "\270f"; } .glyphicon-glass:before { content: "\e001"; } .glyphicon-music:before { content: "\e002"; } .glyphicon-search:before { content: "\e003"; } .glyphicon-heart:before { content: "\e005"; } .glyphicon-star:before { content: "\e006"; } .glyphicon-star-empty:before { content: "\e007"; } .glyphicon-user:before { content: "\e008"; } .glyphicon-film:before { content: "\e009"; } .glyphicon-th-large:before { content: "\e010"; } .glyphicon-th:before { content: "\e011"; } .glyphicon-th-list:before { content: "\e012"; } .glyphicon-ok:before { content: "\e013"; } .glyphicon-remove:before { content: "\e014"; } .glyphicon-zoom-in:before { content: "\e015"; } .glyphicon-zoom-out:before { content: "\e016"; } .glyphicon-off:before { content: "\e017"; } .glyphicon-signal:before { content: "\e018"; } .glyphicon-cog:before { content: "\e019"; } .glyphicon-trash:before { content: "\e020"; } .glyphicon-home:before { content: "\e021"; } .glyphicon-file:before { content: "\e022"; } .glyphicon-time:before { content: "\e023"; } .glyphicon-road:before { content: "\e024"; } .glyphicon-download-alt:before { content: "\e025"; } .glyphicon-download:before { content: "\e026"; } .glyphicon-upload:before { content: "\e027"; } .glyphicon-inbox:before { content: "\e028"; } .glyphicon-play-circle:before { content: "\e029"; } .glyphicon-repeat:before { content: "\e030"; } .glyphicon-refresh:before { content: "\e031"; } .glyphicon-list-alt:before { content: "\e032"; } .glyphicon-lock:before { content: "\e033"; } .glyphicon-flag:before { content: "\e034"; } .glyphicon-headphones:before { content: "\e035"; } .glyphicon-volume-off:before { content: "\e036"; } .glyphicon-volume-down:before { content: "\e037"; } .glyphicon-volume-up:before { content: "\e038"; } .glyphicon-qrcode:before { content: "\e039"; } .glyphicon-barcode:before { content: "\e040"; } .glyphicon-tag:before { content: "\e041"; } .glyphicon-tags:before { content: "\e042"; } .glyphicon-book:before { content: "\e043"; } .glyphicon-bookmark:before { content: "\e044"; } .glyphicon-print:before { content: "\e045"; } .glyphicon-camera:before { content: "\e046"; } .glyphicon-font:before { content: "\e047"; } .glyphicon-bold:before { content: "\e048"; } .glyphicon-italic:before { content: "\e049"; } .glyphicon-text-height:before { content: "\e050"; } .glyphicon-text-width:before { content: "\e051"; } .glyphicon-align-left:before { content: "\e052"; } .glyphicon-align-center:before { content: "\e053"; } .glyphicon-align-right:before { content: "\e054"; } .glyphicon-align-justify:before { content: "\e055"; } .glyphicon-list:before { content: "\e056"; } .glyphicon-indent-left:before { content: "\e057"; } .glyphicon-indent-right:before { content: "\e058"; } .glyphicon-facetime-video:before { content: "\e059"; } .glyphicon-picture:before { content: "\e060"; } .glyphicon-map-marker:before { content: "\e062"; } .glyphicon-adjust:before { content: "\e063"; } .glyphicon-tint:before { content: "\e064"; } .glyphicon-edit:before { content: "\e065"; } .glyphicon-share:before { content: "\e066"; } .glyphicon-check:before { content: "\e067"; } .glyphicon-move:before { content: "\e068"; } .glyphicon-step-backward:before { content: "\e069"; } .glyphicon-fast-backward:before { content: "\e070"; } .glyphicon-backward:before { content: "\e071"; } .glyphicon-play:before { content: "\e072"; } .glyphicon-pause:before { content: "\e073"; } .glyphicon-stop:before { content: "\e074"; } .glyphicon-forward:before { content: "\e075"; } .glyphicon-fast-forward:before { content: "\e076"; } .glyphicon-step-forward:before { content: "\e077"; } .glyphicon-eject:before { content: "\e078"; } .glyphicon-chevron-left:before { content: "\e079"; } .glyphicon-chevron-right:before { content: "\e080"; } .glyphicon-plus-sign:before { content: "\e081"; } .glyphicon-minus-sign:before { content: "\e082"; } .glyphicon-remove-sign:before { content: "\e083"; } .glyphicon-ok-sign:before { content: "\e084"; } .glyphicon-question-sign:before { content: "\e085"; } .glyphicon-info-sign:before { content: "\e086"; } .glyphicon-screenshot:before { content: "\e087"; } .glyphicon-remove-circle:before { content: "\e088"; } .glyphicon-ok-circle:before { content: "\e089"; } .glyphicon-ban-circle:before { content: "\e090"; } .glyphicon-arrow-left:before { content: "\e091"; } .glyphicon-arrow-right:before { content: "\e092"; } .glyphicon-arrow-up:before { content: "\e093"; } .glyphicon-arrow-down:before { content: "\e094"; } .glyphicon-share-alt:before { content: "\e095"; } .glyphicon-resize-full:before { content: "\e096"; } .glyphicon-resize-small:before { content: "\e097"; } .glyphicon-exclamation-sign:before { content: "\e101"; } .glyphicon-gift:before { content: "\e102"; } .glyphicon-leaf:before { content: "\e103"; } .glyphicon-fire:before { content: "\e104"; } .glyphicon-eye-open:before { content: "\e105"; } .glyphicon-eye-close:before { content: "\e106"; } .glyphicon-warning-sign:before { content: "\e107"; } .glyphicon-plane:before { content: "\e108"; } .glyphicon-calendar:before { content: "\e109"; } .glyphicon-random:before { content: "\e110"; } .glyphicon-comment:before { content: "\e111"; } .glyphicon-magnet:before { content: "\e112"; } .glyphicon-chevron-up:before { content: "\e113"; } .glyphicon-chevron-down:before { content: "\e114"; } .glyphicon-retweet:before { content: "\e115"; } .glyphicon-shopping-cart:before { content: "\e116"; } .glyphicon-folder-close:before { content: "\e117"; } .glyphicon-folder-open:before { content: "\e118"; } .glyphicon-resize-vertical:before { content: "\e119"; } .glyphicon-resize-horizontal:before { content: "\e120"; } .glyphicon-hdd:before { content: "\e121"; } .glyphicon-bullhorn:before { content: "\e122"; } .glyphicon-bell:before { content: "\e123"; } .glyphicon-certificate:before { content: "\e124"; } .glyphicon-thumbs-up:before { content: "\e125"; } .glyphicon-thumbs-down:before { content: "\e126"; } .glyphicon-hand-right:before { content: "\e127"; } .glyphicon-hand-left:before { content: "\e128"; } .glyphicon-hand-up:before { content: "\e129"; } .glyphicon-hand-down:before { content: "\e130"; } .glyphicon-circle-arrow-right:before { content: "\e131"; } .glyphicon-circle-arrow-left:before { content: "\e132"; } .glyphicon-circle-arrow-up:before { content: "\e133"; } .glyphicon-circle-arrow-down:before { content: "\e134"; } .glyphicon-globe:before { content: "\e135"; } .glyphicon-wrench:before { content: "\e136"; } .glyphicon-tasks:before { content: "\e137"; } .glyphicon-filter:before { content: "\e138"; } .glyphicon-briefcase:before { content: "\e139"; } .glyphicon-fullscreen:before { content: "\e140"; } .glyphicon-dashboard:before { content: "\e141"; } .glyphicon-paperclip:before { content: "\e142"; } .glyphicon-heart-empty:before { content: "\e143"; } .glyphicon-link:before { content: "\e144"; } .glyphicon-phone:before { content: "\e145"; } .glyphicon-pushpin:before { content: "\e146"; } .glyphicon-usd:before { content: "\e148"; } .glyphicon-gbp:before { content: "\e149"; } .glyphicon-sort:before { content: "\e150"; } .glyphicon-sort-by-alphabet:before { content: "\e151"; } .glyphicon-sort-by-alphabet-alt:before { content: "\e152"; } .glyphicon-sort-by-order:before { content: "\e153"; } .glyphicon-sort-by-order-alt:before { content: "\e154"; } .glyphicon-sort-by-attributes:before { content: "\e155"; } .glyphicon-sort-by-attributes-alt:before { content: "\e156"; } .glyphicon-unchecked:before { content: "\e157"; } .glyphicon-expand:before { content: "\e158"; } .glyphicon-collapse-down:before { content: "\e159"; } .glyphicon-collapse-up:before { content: "\e160"; } .glyphicon-log-in:before { content: "\e161"; } .glyphicon-flash:before { content: "\e162"; } .glyphicon-log-out:before { content: "\e163"; } .glyphicon-new-window:before { content: "\e164"; } .glyphicon-record:before { content: "\e165"; } .glyphicon-save:before { content: "\e166"; } .glyphicon-open:before { content: "\e167"; } .glyphicon-saved:before { content: "\e168"; } .glyphicon-import:before { content: "\e169"; } .glyphicon-export:before { content: "\e170"; } .glyphicon-send:before { content: "\e171"; } .glyphicon-floppy-disk:before { content: "\e172"; } .glyphicon-floppy-saved:before { content: "\e173"; } .glyphicon-floppy-remove:before { content: "\e174"; } .glyphicon-floppy-save:before { content: "\e175"; } .glyphicon-floppy-open:before { content: "\e176"; } .glyphicon-credit-card:before { content: "\e177"; } .glyphicon-transfer:before { content: "\e178"; } .glyphicon-cutlery:before { content: "\e179"; } .glyphicon-header:before { content: "\e180"; } .glyphicon-compressed:before { content: "\e181"; } .glyphicon-earphone:before { content: "\e182"; } .glyphicon-phone-alt:before { content: "\e183"; } .glyphicon-tower:before { content: "\e184"; } .glyphicon-stats:before { content: "\e185"; } .glyphicon-sd-video:before { content: "\e186"; } .glyphicon-hd-video:before { content: "\e187"; } .glyphicon-subtitles:before { content: "\e188"; } .glyphicon-sound-stereo:before { content: "\e189"; } .glyphicon-sound-dolby:before { content: "\e190"; } .glyphicon-sound-5-1:before { content: "\e191"; } .glyphicon-sound-6-1:before { content: "\e192"; } .glyphicon-sound-7-1:before { content: "\e193"; } .glyphicon-copyright-mark:before { content: "\e194"; } .glyphicon-registration-mark:before { content: "\e195"; } .glyphicon-cloud-download:before { content: "\e197"; } .glyphicon-cloud-upload:before { content: "\e198"; } .glyphicon-tree-conifer:before { content: "\e199"; } .glyphicon-tree-deciduous:before { content: "\e200"; } .glyphicon-cd:before { content: "\e201"; } .glyphicon-save-file:before { content: "\e202"; } .glyphicon-open-file:before { content: "\e203"; } .glyphicon-level-up:before { content: "\e204"; } .glyphicon-copy:before { content: "\e205"; } .glyphicon-paste:before { content: "\e206"; } .glyphicon-alert:before { content: "\e209"; } .glyphicon-equalizer:before { content: "\e210"; } .glyphicon-king:before { content: "\e211"; } .glyphicon-queen:before { content: "\e212"; } .glyphicon-pawn:before { content: "\e213"; } .glyphicon-bishop:before { content: "\e214"; } .glyphicon-knight:before { content: "\e215"; } .glyphicon-baby-formula:before { content: "\e216"; } .glyphicon-tent:before { content: "\26fa"; } .glyphicon-blackboard:before { content: "\e218"; } .glyphicon-bed:before { content: "\e219"; } .glyphicon-apple:before { content: "\f8ff"; } .glyphicon-erase:before { content: "\e221"; } .glyphicon-hourglass:before { content: "\231b"; } .glyphicon-lamp:before { content: "\e223"; } .glyphicon-duplicate:before { content: "\e224"; } .glyphicon-piggy-bank:before { content: "\e225"; } .glyphicon-scissors:before { content: "\e226"; } .glyphicon-bitcoin:before { content: "\e227"; } .glyphicon-btc:before { content: "\e227"; } .glyphicon-xbt:before { content: "\e227"; } .glyphicon-yen:before { content: "\00a5"; } .glyphicon-jpy:before { content: "\00a5"; } .glyphicon-ruble:before { content: "\20bd"; } .glyphicon-rub:before { content: "\20bd"; } .glyphicon-scale:before { content: "\e230"; } .glyphicon-ice-lolly:before { content: "\e231"; } .glyphicon-ice-lolly-tasted:before { content: "\e232"; } .glyphicon-education:before { content: "\e233"; } .glyphicon-option-horizontal:before { content: "\e234"; } .glyphicon-option-vertical:before { content: "\e235"; } .glyphicon-menu-hamburger:before { content: "\e236"; } .glyphicon-modal-window:before { content: "\e237"; } .glyphicon-oil:before { content: "\e238"; } .glyphicon-grain:before { content: "\e239"; } .glyphicon-sunglasses:before { content: "\e240"; } .glyphicon-text-size:before { content: "\e241"; } .glyphicon-text-color:before { content: "\e242"; } .glyphicon-text-background:before { content: "\e243"; } .glyphicon-object-align-top:before { content: "\e244"; } .glyphicon-object-align-bottom:before { content: "\e245"; } .glyphicon-object-align-horizontal:before { content: "\e246"; } .glyphicon-object-align-left:before { content: "\e247"; } .glyphicon-object-align-vertical:before { content: "\e248"; } .glyphicon-object-align-right:before { content: "\e249"; } .glyphicon-triangle-right:before { content: "\e250"; } .glyphicon-triangle-left:before { content: "\e251"; } .glyphicon-triangle-bottom:before { content: "\e252"; } .glyphicon-triangle-top:before { content: "\e253"; } .glyphicon-console:before { content: "\e254"; } .glyphicon-superscript:before { content: "\e255"; } .glyphicon-subscript:before { content: "\e256"; } .glyphicon-menu-left:before { content: "\e257"; } .glyphicon-menu-right:before { content: "\e258"; } .glyphicon-menu-down:before { content: "\e259"; } .glyphicon-menu-up:before { content: "\e260"; } * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } html { font-size: 10px; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } body { font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; font-size: 15px; line-height: 1.846; color: #444; background-color: #fff; } input, button, select, textarea { font-family: inherit; font-size: inherit; line-height: inherit; } a { color: #5a9ddb; text-decoration: none; } a:hover, a:focus { color: #2a77bf; text-decoration: underline; } a:focus { outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } figure { margin: 0; } img { vertical-align: middle; } .img-responsive { display: block; max-width: 100%; height: auto; } .img-rounded { border-radius: 3px; } .img-thumbnail { padding: 4px; line-height: 1.846; background-color: #fff; border: 1px solid #ddd; border-radius: 3px; -webkit-transition: all 0.2s ease-in-out; -o-transition: all 0.2s ease-in-out; transition: all 0.2s ease-in-out; display: inline-block; max-width: 100%; height: auto; } .img-circle { border-radius: 50%; } hr { margin-top: 27px; margin-bottom: 27px; border: 0; border-top: 1px solid #eeeeee; } .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0, 0, 0, 0); border: 0; } .sr-only-focusable:active, .sr-only-focusable:focus { position: static; width: auto; height: auto; margin: 0; overflow: visible; clip: auto; } [role="button"] { cursor: pointer; } h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 { font-family: inherit; font-weight: 300; line-height: 1.1; color: #444; } h1 small, h1 .small, h2 small, h2 .small, h3 small, h3 .small, h4 small, h4 .small, h5 small, h5 .small, h6 small, h6 .small, .h1 small, .h1 .small, .h2 small, .h2 .small, .h3 small, .h3 .small, .h4 small, .h4 .small, .h5 small, .h5 .small, .h6 small, .h6 .small { font-weight: normal; line-height: 1; color: #bbb; } h1, .h1, h2, .h2, h3, .h3 { margin-top: 27px; margin-bottom: 13.5px; } h1 small, h1 .small, .h1 small, .h1 .small, h2 small, h2 .small, .h2 small, .h2 .small, h3 small, h3 .small, .h3 small, .h3 .small { font-size: 65%; } h4, .h4, h5, .h5, h6, .h6 { margin-top: 13.5px; margin-bottom: 13.5px; } h4 small, h4 .small, .h4 small, .h4 .small, h5 small, h5 .small, .h5 small, .h5 .small, h6 small, h6 .small, .h6 small, .h6 .small { font-size: 75%; } h1, .h1 { font-size: 48px; } h2, .h2 { font-size: 40px; } h3, .h3 { font-size: 32px; } h4, .h4 { font-size: 24px; } h5, .h5 { font-size: 20px; } h6, .h6 { font-size: 14px; } p { margin: 0 0 13.5px; } .lead { margin-bottom: 27px; font-size: 17px; font-weight: 300; line-height: 1.4; } @media (min-width: 768px) { .lead { font-size: 22.5px; } } small, .small { font-size: 86%; } mark, .mark { background-color: #ffe0b2; padding: .2em; } .text-left { text-align: left; } .text-right { text-align: right; } .text-center { text-align: center; } .text-justify { text-align: justify; } .text-nowrap { white-space: nowrap; } .text-lowercase { text-transform: lowercase; } .text-uppercase, .initialism { text-transform: uppercase; } .text-capitalize { text-transform: capitalize; } .text-muted { color: #bbb; } .text-primary { color: #5a9ddb; } a.text-primary:hover, a.text-primary:focus { color: #3084d2; } .text-success { color: #4CAF50; } a.text-success:hover, a.text-success:focus { color: #3d8b40; } .text-info { color: #9C27B0; } a.text-info:hover, a.text-info:focus { color: #771e86; } .text-warning { color: #ff9800; } a.text-warning:hover, a.text-warning:focus { color: #cc7a00; } .text-danger { color: #e51c23; } a.text-danger:hover, a.text-danger:focus { color: #b9151b; } .bg-primary { color: #fff; } .bg-primary { background-color: #5a9ddb; } a.bg-primary:hover, a.bg-primary:focus { background-color: #3084d2; } .bg-success { background-color: #dff0d8; } a.bg-success:hover, a.bg-success:focus { background-color: #c1e2b3; } .bg-info { background-color: #e1bee7; } a.bg-info:hover, a.bg-info:focus { background-color: #d099d9; } .bg-warning { background-color: #ffe0b2; } a.bg-warning:hover, a.bg-warning:focus { background-color: #ffcb7f; } .bg-danger { background-color: #f9bdbb; } a.bg-danger:hover, a.bg-danger:focus { background-color: #f5908c; } .page-header { padding-bottom: 12.5px; margin: 54px 0 27px; border-bottom: 1px solid #eeeeee; } ul, ol { margin-top: 0; margin-bottom: 13.5px; } ul ul, ul ol, ol ul, ol ol { margin-bottom: 0; } .list-unstyled { padding-left: 0; list-style: none; } .list-inline { padding-left: 0; list-style: none; margin-left: -5px; } .list-inline > li { display: inline-block; padding-left: 5px; padding-right: 5px; } dl { margin-top: 0; margin-bottom: 27px; } dt, dd { line-height: 1.846; } dt { font-weight: bold; } dd { margin-left: 0; } .dl-horizontal dd:before, .dl-horizontal dd:after { content: " "; display: table; } .dl-horizontal dd:after { clear: both; } @media (min-width: 768px) { .dl-horizontal dt { float: left; width: 160px; clear: left; text-align: right; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .dl-horizontal dd { margin-left: 180px; } } abbr[title], abbr[data-original-title] { cursor: help; border-bottom: 1px dotted #bbb; } .initialism { font-size: 90%; } blockquote { padding: 13.5px 27px; margin: 0 0 27px; font-size: 18.75px; border-left: 5px solid #eeeeee; } blockquote p:last-child, blockquote ul:last-child, blockquote ol:last-child { margin-bottom: 0; } blockquote footer, blockquote small, blockquote .small { display: block; font-size: 80%; line-height: 1.846; color: #bbb; } blockquote footer:before, blockquote small:before, blockquote .small:before { content: '\2014 \00A0'; } .blockquote-reverse, blockquote.pull-right { padding-right: 15px; padding-left: 0; border-right: 5px solid #eeeeee; border-left: 0; text-align: right; } .blockquote-reverse footer:before, .blockquote-reverse small:before, .blockquote-reverse .small:before, blockquote.pull-right footer:before, blockquote.pull-right small:before, blockquote.pull-right .small:before { content: ''; } .blockquote-reverse footer:after, .blockquote-reverse small:after, .blockquote-reverse .small:after, blockquote.pull-right footer:after, blockquote.pull-right small:after, blockquote.pull-right .small:after { content: '\00A0 \2014'; } address { margin-bottom: 27px; font-style: normal; line-height: 1.846; } code, kbd, pre, samp { font-family: "Source Code Pro", Menlo, Monaco, Consolas, "Courier New", monospace; } code { padding: 2px 4px; font-size: 90%; color: #444; background-color: #f2f2f2; border-radius: 3px; } kbd { padding: 2px 4px; font-size: 90%; color: #fff; background-color: #333; border-radius: 3px; box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.25); } kbd kbd { padding: 0; font-size: 100%; font-weight: bold; box-shadow: none; } pre { display: block; padding: 13px; margin: 0 0 13.5px; font-size: 14px; line-height: 1.846; word-break: break-all; word-wrap: break-word; color: #212121; background-color: #f5f5f5; border: 1px solid #ccc; border-radius: 3px; } pre code { padding: 0; font-size: inherit; color: inherit; white-space: pre-wrap; background-color: transparent; border-radius: 0; } .pre-scrollable { max-height: 340px; overflow-y: scroll; } .container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px; } .container:before, .container:after { content: " "; display: table; } .container:after { clear: both; } @media (min-width: 768px) { .container { width: 750px; } } @media (min-width: 992px) { .container { width: 970px; } } @media (min-width: 1200px) { .container { width: 1170px; } } .container-fluid { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px; } .container-fluid:before, .container-fluid:after { content: " "; display: table; } .container-fluid:after { clear: both; } .row { margin-left: -15px; margin-right: -15px; } .row:before, .row:after { content: " "; display: table; } .row:after { clear: both; } .col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 { position: relative; min-height: 1px; padding-left: 15px; padding-right: 15px; } .col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 { float: left; } .col-xs-1 { width: 8.3333333333%; } .col-xs-2 { width: 16.6666666667%; } .col-xs-3 { width: 25%; } .col-xs-4 { width: 33.3333333333%; } .col-xs-5 { width: 41.6666666667%; } .col-xs-6 { width: 50%; } .col-xs-7 { width: 58.3333333333%; } .col-xs-8 { width: 66.6666666667%; } .col-xs-9 { width: 75%; } .col-xs-10 { width: 83.3333333333%; } .col-xs-11 { width: 91.6666666667%; } .col-xs-12 { width: 100%; } .col-xs-pull-0 { right: auto; } .col-xs-pull-1 { right: 8.3333333333%; } .col-xs-pull-2 { right: 16.6666666667%; } .col-xs-pull-3 { right: 25%; } .col-xs-pull-4 { right: 33.3333333333%; } .col-xs-pull-5 { right: 41.6666666667%; } .col-xs-pull-6 { right: 50%; } .col-xs-pull-7 { right: 58.3333333333%; } .col-xs-pull-8 { right: 66.6666666667%; } .col-xs-pull-9 { right: 75%; } .col-xs-pull-10 { right: 83.3333333333%; } .col-xs-pull-11 { right: 91.6666666667%; } .col-xs-pull-12 { right: 100%; } .col-xs-push-0 { left: auto; } .col-xs-push-1 { left: 8.3333333333%; } .col-xs-push-2 { left: 16.6666666667%; } .col-xs-push-3 { left: 25%; } .col-xs-push-4 { left: 33.3333333333%; } .col-xs-push-5 { left: 41.6666666667%; } .col-xs-push-6 { left: 50%; } .col-xs-push-7 { left: 58.3333333333%; } .col-xs-push-8 { left: 66.6666666667%; } .col-xs-push-9 { left: 75%; } .col-xs-push-10 { left: 83.3333333333%; } .col-xs-push-11 { left: 91.6666666667%; } .col-xs-push-12 { left: 100%; } .col-xs-offset-0 { margin-left: 0%; } .col-xs-offset-1 { margin-left: 8.3333333333%; } .col-xs-offset-2 { margin-left: 16.6666666667%; } .col-xs-offset-3 { margin-left: 25%; } .col-xs-offset-4 { margin-left: 33.3333333333%; } .col-xs-offset-5 { margin-left: 41.6666666667%; } .col-xs-offset-6 { margin-left: 50%; } .col-xs-offset-7 { margin-left: 58.3333333333%; } .col-xs-offset-8 { margin-left: 66.6666666667%; } .col-xs-offset-9 { margin-left: 75%; } .col-xs-offset-10 { margin-left: 83.3333333333%; } .col-xs-offset-11 { margin-left: 91.6666666667%; } .col-xs-offset-12 { margin-left: 100%; } @media (min-width: 768px) { .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 { float: left; } .col-sm-1 { width: 8.3333333333%; } .col-sm-2 { width: 16.6666666667%; } .col-sm-3 { width: 25%; } .col-sm-4 { width: 33.3333333333%; } .col-sm-5 { width: 41.6666666667%; } .col-sm-6 { width: 50%; } .col-sm-7 { width: 58.3333333333%; } .col-sm-8 { width: 66.6666666667%; } .col-sm-9 { width: 75%; } .col-sm-10 { width: 83.3333333333%; } .col-sm-11 { width: 91.6666666667%; } .col-sm-12 { width: 100%; } .col-sm-pull-0 { right: auto; } .col-sm-pull-1 { right: 8.3333333333%; } .col-sm-pull-2 { right: 16.6666666667%; } .col-sm-pull-3 { right: 25%; } .col-sm-pull-4 { right: 33.3333333333%; } .col-sm-pull-5 { right: 41.6666666667%; } .col-sm-pull-6 { right: 50%; } .col-sm-pull-7 { right: 58.3333333333%; } .col-sm-pull-8 { right: 66.6666666667%; } .col-sm-pull-9 { right: 75%; } .col-sm-pull-10 { right: 83.3333333333%; } .col-sm-pull-11 { right: 91.6666666667%; } .col-sm-pull-12 { right: 100%; } .col-sm-push-0 { left: auto; } .col-sm-push-1 { left: 8.3333333333%; } .col-sm-push-2 { left: 16.6666666667%; } .col-sm-push-3 { left: 25%; } .col-sm-push-4 { left: 33.3333333333%; } .col-sm-push-5 { left: 41.6666666667%; } .col-sm-push-6 { left: 50%; } .col-sm-push-7 { left: 58.3333333333%; } .col-sm-push-8 { left: 66.6666666667%; } .col-sm-push-9 { left: 75%; } .col-sm-push-10 { left: 83.3333333333%; } .col-sm-push-11 { left: 91.6666666667%; } .col-sm-push-12 { left: 100%; } .col-sm-offset-0 { margin-left: 0%; } .col-sm-offset-1 { margin-left: 8.3333333333%; } .col-sm-offset-2 { margin-left: 16.6666666667%; } .col-sm-offset-3 { margin-left: 25%; } .col-sm-offset-4 { margin-left: 33.3333333333%; } .col-sm-offset-5 { margin-left: 41.6666666667%; } .col-sm-offset-6 { margin-left: 50%; } .col-sm-offset-7 { margin-left: 58.3333333333%; } .col-sm-offset-8 { margin-left: 66.6666666667%; } .col-sm-offset-9 { margin-left: 75%; } .col-sm-offset-10 { margin-left: 83.3333333333%; } .col-sm-offset-11 { margin-left: 91.6666666667%; } .col-sm-offset-12 { margin-left: 100%; } } @media (min-width: 992px) { .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 { float: left; } .col-md-1 { width: 8.3333333333%; } .col-md-2 { width: 16.6666666667%; } .col-md-3 { width: 25%; } .col-md-4 { width: 33.3333333333%; } .col-md-5 { width: 41.6666666667%; } .col-md-6 { width: 50%; } .col-md-7 { width: 58.3333333333%; } .col-md-8 { width: 66.6666666667%; } .col-md-9 { width: 75%; } .col-md-10 { width: 83.3333333333%; } .col-md-11 { width: 91.6666666667%; } .col-md-12 { width: 100%; } .col-md-pull-0 { right: auto; } .col-md-pull-1 { right: 8.3333333333%; } .col-md-pull-2 { right: 16.6666666667%; } .col-md-pull-3 { right: 25%; } .col-md-pull-4 { right: 33.3333333333%; } .col-md-pull-5 { right: 41.6666666667%; } .col-md-pull-6 { right: 50%; } .col-md-pull-7 { right: 58.3333333333%; } .col-md-pull-8 { right: 66.6666666667%; } .col-md-pull-9 { right: 75%; } .col-md-pull-10 { right: 83.3333333333%; } .col-md-pull-11 { right: 91.6666666667%; } .col-md-pull-12 { right: 100%; } .col-md-push-0 { left: auto; } .col-md-push-1 { left: 8.3333333333%; } .col-md-push-2 { left: 16.6666666667%; } .col-md-push-3 { left: 25%; } .col-md-push-4 { left: 33.3333333333%; } .col-md-push-5 { left: 41.6666666667%; } .col-md-push-6 { left: 50%; } .col-md-push-7 { left: 58.3333333333%; } .col-md-push-8 { left: 66.6666666667%; } .col-md-push-9 { left: 75%; } .col-md-push-10 { left: 83.3333333333%; } .col-md-push-11 { left: 91.6666666667%; } .col-md-push-12 { left: 100%; } .col-md-offset-0 { margin-left: 0%; } .col-md-offset-1 { margin-left: 8.3333333333%; } .col-md-offset-2 { margin-left: 16.6666666667%; } .col-md-offset-3 { margin-left: 25%; } .col-md-offset-4 { margin-left: 33.3333333333%; } .col-md-offset-5 { margin-left: 41.6666666667%; } .col-md-offset-6 { margin-left: 50%; } .col-md-offset-7 { margin-left: 58.3333333333%; } .col-md-offset-8 { margin-left: 66.6666666667%; } .col-md-offset-9 { margin-left: 75%; } .col-md-offset-10 { margin-left: 83.3333333333%; } .col-md-offset-11 { margin-left: 91.6666666667%; } .col-md-offset-12 { margin-left: 100%; } } @media (min-width: 1200px) { .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 { float: left; } .col-lg-1 { width: 8.3333333333%; } .col-lg-2 { width: 16.6666666667%; } .col-lg-3 { width: 25%; } .col-lg-4 { width: 33.3333333333%; } .col-lg-5 { width: 41.6666666667%; } .col-lg-6 { width: 50%; } .col-lg-7 { width: 58.3333333333%; } .col-lg-8 { width: 66.6666666667%; } .col-lg-9 { width: 75%; } .col-lg-10 { width: 83.3333333333%; } .col-lg-11 { width: 91.6666666667%; } .col-lg-12 { width: 100%; } .col-lg-pull-0 { right: auto; } .col-lg-pull-1 { right: 8.3333333333%; } .col-lg-pull-2 { right: 16.6666666667%; } .col-lg-pull-3 { right: 25%; } .col-lg-pull-4 { right: 33.3333333333%; } .col-lg-pull-5 { right: 41.6666666667%; } .col-lg-pull-6 { right: 50%; } .col-lg-pull-7 { right: 58.3333333333%; } .col-lg-pull-8 { right: 66.6666666667%; } .col-lg-pull-9 { right: 75%; } .col-lg-pull-10 { right: 83.3333333333%; } .col-lg-pull-11 { right: 91.6666666667%; } .col-lg-pull-12 { right: 100%; } .col-lg-push-0 { left: auto; } .col-lg-push-1 { left: 8.3333333333%; } .col-lg-push-2 { left: 16.6666666667%; } .col-lg-push-3 { left: 25%; } .col-lg-push-4 { left: 33.3333333333%; } .col-lg-push-5 { left: 41.6666666667%; } .col-lg-push-6 { left: 50%; } .col-lg-push-7 { left: 58.3333333333%; } .col-lg-push-8 { left: 66.6666666667%; } .col-lg-push-9 { left: 75%; } .col-lg-push-10 { left: 83.3333333333%; } .col-lg-push-11 { left: 91.6666666667%; } .col-lg-push-12 { left: 100%; } .col-lg-offset-0 { margin-left: 0%; } .col-lg-offset-1 { margin-left: 8.3333333333%; } .col-lg-offset-2 { margin-left: 16.6666666667%; } .col-lg-offset-3 { margin-left: 25%; } .col-lg-offset-4 { margin-left: 33.3333333333%; } .col-lg-offset-5 { margin-left: 41.6666666667%; } .col-lg-offset-6 { margin-left: 50%; } .col-lg-offset-7 { margin-left: 58.3333333333%; } .col-lg-offset-8 { margin-left: 66.6666666667%; } .col-lg-offset-9 { margin-left: 75%; } .col-lg-offset-10 { margin-left: 83.3333333333%; } .col-lg-offset-11 { margin-left: 91.6666666667%; } .col-lg-offset-12 { margin-left: 100%; } } table { background-color: transparent; } caption { padding-top: 8px; padding-bottom: 8px; color: #bbb; text-align: left; } th { text-align: left; } .table { width: 100%; max-width: 100%; margin-bottom: 27px; } .table > thead > tr > th, .table > thead > tr > td, .table > tbody > tr > th, .table > tbody > tr > td, .table > tfoot > tr > th, .table > tfoot > tr > td { padding: 8px; line-height: 1.846; vertical-align: top; border-top: 1px solid #ddd; } .table > thead > tr > th { vertical-align: bottom; border-bottom: 2px solid #ddd; } .table > caption + thead > tr:first-child > th, .table > caption + thead > tr:first-child > td, .table > colgroup + thead > tr:first-child > th, .table > colgroup + thead > tr:first-child > td, .table > thead:first-child > tr:first-child > th, .table > thead:first-child > tr:first-child > td { border-top: 0; } .table > tbody + tbody { border-top: 2px solid #ddd; } .table .table { background-color: #fff; } .table-condensed > thead > tr > th, .table-condensed > thead > tr > td, .table-condensed > tbody > tr > th, .table-condensed > tbody > tr > td, .table-condensed > tfoot > tr > th, .table-condensed > tfoot > tr > td { padding: 5px; } .table-bordered { border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > th, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > th, .table-bordered > tfoot > tr > td { border: 1px solid #ddd; } .table-bordered > thead > tr > th, .table-bordered > thead > tr > td { border-bottom-width: 2px; } .table-striped > tbody > tr:nth-of-type(odd) { background-color: #f9f9f9; } .table-hover > tbody > tr:hover { background-color: #f5f5f5; } table col[class*="col-"] { position: static; float: none; display: table-column; } table td[class*="col-"], table th[class*="col-"] { position: static; float: none; display: table-cell; } .table > thead > tr > td.active, .table > thead > tr > th.active, .table > thead > tr.active > td, .table > thead > tr.active > th, .table > tbody > tr > td.active, .table > tbody > tr > th.active, .table > tbody > tr.active > td, .table > tbody > tr.active > th, .table > tfoot > tr > td.active, .table > tfoot > tr > th.active, .table > tfoot > tr.active > td, .table > tfoot > tr.active > th { background-color: #f5f5f5; } .table-hover > tbody > tr > td.active:hover, .table-hover > tbody > tr > th.active:hover, .table-hover > tbody > tr.active:hover > td, .table-hover > tbody > tr:hover > .active, .table-hover > tbody > tr.active:hover > th { background-color: #e8e8e8; } .table > thead > tr > td.success, .table > thead > tr > th.success, .table > thead > tr.success > td, .table > thead > tr.success > th, .table > tbody > tr > td.success, .table > tbody > tr > th.success, .table > tbody > tr.success > td, .table > tbody > tr.success > th, .table > tfoot > tr > td.success, .table > tfoot > tr > th.success, .table > tfoot > tr.success > td, .table > tfoot > tr.success > th { background-color: #dff0d8; } .table-hover > tbody > tr > td.success:hover, .table-hover > tbody > tr > th.success:hover, .table-hover > tbody > tr.success:hover > td, .table-hover > tbody > tr:hover > .success, .table-hover > tbody > tr.success:hover > th { background-color: #d0e9c6; } .table > thead > tr > td.info, .table > thead > tr > th.info, .table > thead > tr.info > td, .table > thead > tr.info > th, .table > tbody > tr > td.info, .table > tbody > tr > th.info, .table > tbody > tr.info > td, .table > tbody > tr.info > th, .table > tfoot > tr > td.info, .table > tfoot > tr > th.info, .table > tfoot > tr.info > td, .table > tfoot > tr.info > th { background-color: #e1bee7; } .table-hover > tbody > tr > td.info:hover, .table-hover > tbody > tr > th.info:hover, .table-hover > tbody > tr.info:hover > td, .table-hover > tbody > tr:hover > .info, .table-hover > tbody > tr.info:hover > th { background-color: #d8abe0; } .table > thead > tr > td.warning, .table > thead > tr > th.warning, .table > thead > tr.warning > td, .table > thead > tr.warning > th, .table > tbody > tr > td.warning, .table > tbody > tr > th.warning, .table > tbody > tr.warning > td, .table > tbody > tr.warning > th, .table > tfoot > tr > td.warning, .table > tfoot > tr > th.warning, .table > tfoot > tr.warning > td, .table > tfoot > tr.warning > th { background-color: #ffe0b2; } .table-hover > tbody > tr > td.warning:hover, .table-hover > tbody > tr > th.warning:hover, .table-hover > tbody > tr.warning:hover > td, .table-hover > tbody > tr:hover > .warning, .table-hover > tbody > tr.warning:hover > th { background-color: #ffd699; } .table > thead > tr > td.danger, .table > thead > tr > th.danger, .table > thead > tr.danger > td, .table > thead > tr.danger > th, .table > tbody > tr > td.danger, .table > tbody > tr > th.danger, .table > tbody > tr.danger > td, .table > tbody > tr.danger > th, .table > tfoot > tr > td.danger, .table > tfoot > tr > th.danger, .table > tfoot > tr.danger > td, .table > tfoot > tr.danger > th { background-color: #f9bdbb; } .table-hover > tbody > tr > td.danger:hover, .table-hover > tbody > tr > th.danger:hover, .table-hover > tbody > tr.danger:hover > td, .table-hover > tbody > tr:hover > .danger, .table-hover > tbody > tr.danger:hover > th { background-color: #f7a6a4; } .table-responsive { overflow-x: auto; min-height: 0.01%; } @media screen and (max-width: 767px) { .table-responsive { width: 100%; margin-bottom: 20.25px; overflow-y: hidden; -ms-overflow-style: -ms-autohiding-scrollbar; border: 1px solid #ddd; } .table-responsive > .table { margin-bottom: 0; } .table-responsive > .table > thead > tr > th, .table-responsive > .table > thead > tr > td, .table-responsive > .table > tbody > tr > th, .table-responsive > .table > tbody > tr > td, .table-responsive > .table > tfoot > tr > th, .table-responsive > .table > tfoot > tr > td { white-space: nowrap; } .table-responsive > .table-bordered { border: 0; } .table-responsive > .table-bordered > thead > tr > th:first-child, .table-responsive > .table-bordered > thead > tr > td:first-child, .table-responsive > .table-bordered > tbody > tr > th:first-child, .table-responsive > .table-bordered > tbody > tr > td:first-child, .table-responsive > .table-bordered > tfoot > tr > th:first-child, .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } .table-responsive > .table-bordered > thead > tr > th:last-child, .table-responsive > .table-bordered > thead > tr > td:last-child, .table-responsive > .table-bordered > tbody > tr > th:last-child, .table-responsive > .table-bordered > tbody > tr > td:last-child, .table-responsive > .table-bordered > tfoot > tr > th:last-child, .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } .table-responsive > .table-bordered > tbody > tr:last-child > th, .table-responsive > .table-bordered > tbody > tr:last-child > td, .table-responsive > .table-bordered > tfoot > tr:last-child > th, .table-responsive > .table-bordered > tfoot > tr:last-child > td { border-bottom: 0; } } fieldset { padding: 0; margin: 0; border: 0; min-width: 0; } legend { display: block; width: 100%; padding: 0; margin-bottom: 27px; font-size: 22.5px; line-height: inherit; color: #212121; border: 0; border-bottom: 1px solid #e5e5e5; } label { display: inline-block; max-width: 100%; margin-bottom: 5px; font-weight: bold; } input[type="search"] { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } input[type="radio"], input[type="checkbox"] { margin: 4px 0 0; margin-top: 1px \9; line-height: normal; } input[type="file"] { display: block; } input[type="range"] { display: block; width: 100%; } select[multiple], select[size] { height: auto; } input[type="file"]:focus, input[type="radio"]:focus, input[type="checkbox"]:focus { outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } output { display: block; padding-top: 7px; font-size: 15px; line-height: 1.846; color: #666; } .form-control { display: block; width: 100%; height: 41px; padding: 6px 16px; font-size: 15px; line-height: 1.846; color: #666; background-color: transparent; background-image: none; border: 1px solid transparent; border-radius: 3px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; } .form-control:focus { border-color: #66afe9; outline: 0; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6); } .form-control::-moz-placeholder { color: #bbb; opacity: 1; } .form-control:-ms-input-placeholder { color: #bbb; } .form-control::-webkit-input-placeholder { color: #bbb; } .form-control::-ms-expand { border: 0; background-color: transparent; } .form-control[disabled], .form-control[readonly], fieldset[disabled] .form-control { background-color: transparent; opacity: 1; } .form-control[disabled], fieldset[disabled] .form-control { cursor: not-allowed; } textarea.form-control { height: auto; } input[type="search"] { -webkit-appearance: none; } @media screen and (-webkit-min-device-pixel-ratio: 0) { input[type="date"].form-control, input[type="time"].form-control, input[type="datetime-local"].form-control, input[type="month"].form-control { line-height: 41px; } input[type="date"].input-sm, .input-group-sm > input[type="date"].form-control, .input-group-sm > input[type="date"].input-group-addon, .input-group-sm > .input-group-btn > input[type="date"].btn, .input-group-sm input[type="date"], input[type="time"].input-sm, .input-group-sm > input[type="time"].form-control, .input-group-sm > input[type="time"].input-group-addon, .input-group-sm > .input-group-btn > input[type="time"].btn, .input-group-sm input[type="time"], input[type="datetime-local"].input-sm, .input-group-sm > input[type="datetime-local"].form-control, .input-group-sm > input[type="datetime-local"].input-group-addon, .input-group-sm > .input-group-btn > input[type="datetime-local"].btn, .input-group-sm input[type="datetime-local"], input[type="month"].input-sm, .input-group-sm > input[type="month"].form-control, .input-group-sm > input[type="month"].input-group-addon, .input-group-sm > .input-group-btn > input[type="month"].btn, .input-group-sm input[type="month"] { line-height: 31px; } input[type="date"].input-lg, .input-group-lg > input[type="date"].form-control, .input-group-lg > input[type="date"].input-group-addon, .input-group-lg > .input-group-btn > input[type="date"].btn, .input-group-lg input[type="date"], input[type="time"].input-lg, .input-group-lg > input[type="time"].form-control, .input-group-lg > input[type="time"].input-group-addon, .input-group-lg > .input-group-btn > input[type="time"].btn, .input-group-lg input[type="time"], input[type="datetime-local"].input-lg, .input-group-lg > input[type="datetime-local"].form-control, .input-group-lg > input[type="datetime-local"].input-group-addon, .input-group-lg > .input-group-btn > input[type="datetime-local"].btn, .input-group-lg input[type="datetime-local"], input[type="month"].input-lg, .input-group-lg > input[type="month"].form-control, .input-group-lg > input[type="month"].input-group-addon, .input-group-lg > .input-group-btn > input[type="month"].btn, .input-group-lg input[type="month"] { line-height: 48px; } } .form-group { margin-bottom: 15px; } .radio, .checkbox { position: relative; display: block; margin-top: 10px; margin-bottom: 10px; } .radio label, .checkbox label { min-height: 27px; padding-left: 20px; margin-bottom: 0; font-weight: normal; cursor: pointer; } .radio input[type="radio"], .radio-inline input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { position: absolute; margin-left: -20px; margin-top: 4px \9; } .radio + .radio, .checkbox + .checkbox { margin-top: -5px; } .radio-inline, .checkbox-inline { position: relative; display: inline-block; padding-left: 20px; margin-bottom: 0; vertical-align: middle; font-weight: normal; cursor: pointer; } .radio-inline + .radio-inline, .checkbox-inline + .checkbox-inline { margin-top: 0; margin-left: 10px; } input[type="radio"][disabled], input[type="radio"].disabled, fieldset[disabled] input[type="radio"], input[type="checkbox"][disabled], input[type="checkbox"].disabled, fieldset[disabled] input[type="checkbox"] { cursor: not-allowed; } .radio-inline.disabled, fieldset[disabled] .radio-inline, .checkbox-inline.disabled, fieldset[disabled] .checkbox-inline { cursor: not-allowed; } .radio.disabled label, fieldset[disabled] .radio label, .checkbox.disabled label, fieldset[disabled] .checkbox label { cursor: not-allowed; } .form-control-static { padding-top: 7px; padding-bottom: 7px; margin-bottom: 0; min-height: 42px; } .form-control-static.input-lg, .input-group-lg > .form-control-static.form-control, .input-group-lg > .form-control-static.input-group-addon, .input-group-lg > .input-group-btn > .form-control-static.btn, .form-control-static.input-sm, .input-group-sm > .form-control-static.form-control, .input-group-sm > .form-control-static.input-group-addon, .input-group-sm > .input-group-btn > .form-control-static.btn { padding-left: 0; padding-right: 0; } .input-sm, .input-group-sm > .form-control, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .btn { height: 31px; padding: 5px 10px; font-size: 13px; line-height: 1.5; border-radius: 3px; } select.input-sm, .input-group-sm > select.form-control, .input-group-sm > select.input-group-addon, .input-group-sm > .input-group-btn > select.btn { height: 31px; line-height: 31px; } textarea.input-sm, .input-group-sm > textarea.form-control, .input-group-sm > textarea.input-group-addon, .input-group-sm > .input-group-btn > textarea.btn, select[multiple].input-sm, .input-group-sm > select[multiple].form-control, .input-group-sm > select[multiple].input-group-addon, .input-group-sm > .input-group-btn > select[multiple].btn { height: auto; } .form-group-sm .form-control { height: 31px; padding: 5px 10px; font-size: 13px; line-height: 1.5; border-radius: 3px; } .form-group-sm select.form-control { height: 31px; line-height: 31px; } .form-group-sm textarea.form-control, .form-group-sm select[multiple].form-control { height: auto; } .form-group-sm .form-control-static { height: 31px; min-height: 40px; padding: 6px 10px; font-size: 13px; line-height: 1.5; } .input-lg, .input-group-lg > .form-control, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .btn { height: 48px; padding: 10px 16px; font-size: 19px; line-height: 1.3333333; border-radius: 3px; } select.input-lg, .input-group-lg > select.form-control, .input-group-lg > select.input-group-addon, .input-group-lg > .input-group-btn > select.btn { height: 48px; line-height: 48px; } textarea.input-lg, .input-group-lg > textarea.form-control, .input-group-lg > textarea.input-group-addon, .input-group-lg > .input-group-btn > textarea.btn, select[multiple].input-lg, .input-group-lg > select[multiple].form-control, .input-group-lg > select[multiple].input-group-addon, .input-group-lg > .input-group-btn > select[multiple].btn { height: auto; } .form-group-lg .form-control { height: 48px; padding: 10px 16px; font-size: 19px; line-height: 1.3333333; border-radius: 3px; } .form-group-lg select.form-control { height: 48px; line-height: 48px; } .form-group-lg textarea.form-control, .form-group-lg select[multiple].form-control { height: auto; } .form-group-lg .form-control-static { height: 48px; min-height: 46px; padding: 11px 16px; font-size: 19px; line-height: 1.3333333; } .has-feedback { position: relative; } .has-feedback .form-control { padding-right: 51.25px; } .form-control-feedback { position: absolute; top: 0; right: 0; z-index: 2; display: block; width: 41px; height: 41px; line-height: 41px; text-align: center; pointer-events: none; } .input-lg + .form-control-feedback, .input-group-lg > .form-control + .form-control-feedback, .input-group-lg > .input-group-addon + .form-control-feedback, .input-group-lg > .input-group-btn > .btn + .form-control-feedback, .input-group-lg + .form-control-feedback, .form-group-lg .form-control + .form-control-feedback { width: 48px; height: 48px; line-height: 48px; } .input-sm + .form-control-feedback, .input-group-sm > .form-control + .form-control-feedback, .input-group-sm > .input-group-addon + .form-control-feedback, .input-group-sm > .input-group-btn > .btn + .form-control-feedback, .input-group-sm + .form-control-feedback, .form-group-sm .form-control + .form-control-feedback { width: 31px; height: 31px; line-height: 31px; } .has-success .help-block, .has-success .control-label, .has-success .radio, .has-success .checkbox, .has-success .radio-inline, .has-success .checkbox-inline, .has-success.radio label, .has-success.checkbox label, .has-success.radio-inline label, .has-success.checkbox-inline label { color: #4CAF50; } .has-success .form-control { border-color: #4CAF50; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .has-success .form-control:focus { border-color: #3d8b40; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #92cf94; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #92cf94; } .has-success .input-group-addon { color: #4CAF50; border-color: #4CAF50; background-color: #dff0d8; } .has-success .form-control-feedback { color: #4CAF50; } .has-warning .help-block, .has-warning .control-label, .has-warning .radio, .has-warning .checkbox, .has-warning .radio-inline, .has-warning .checkbox-inline, .has-warning.radio label, .has-warning.checkbox label, .has-warning.radio-inline label, .has-warning.checkbox-inline label { color: #ff9800; } .has-warning .form-control { border-color: #ff9800; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .has-warning .form-control:focus { border-color: #cc7a00; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffc166; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ffc166; } .has-warning .input-group-addon { color: #ff9800; border-color: #ff9800; background-color: #ffe0b2; } .has-warning .form-control-feedback { color: #ff9800; } .has-error .help-block, .has-error .control-label, .has-error .radio, .has-error .checkbox, .has-error .radio-inline, .has-error .checkbox-inline, .has-error.radio label, .has-error.checkbox label, .has-error.radio-inline label, .has-error.checkbox-inline label { color: #e51c23; } .has-error .form-control { border-color: #e51c23; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); } .has-error .form-control:focus { border-color: #b9151b; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ef787c; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ef787c; } .has-error .input-group-addon { color: #e51c23; border-color: #e51c23; background-color: #f9bdbb; } .has-error .form-control-feedback { color: #e51c23; } .has-feedback label ~ .form-control-feedback { top: 32px; } .has-feedback label.sr-only ~ .form-control-feedback { top: 0; } .help-block { display: block; margin-top: 5px; margin-bottom: 10px; color: #848484; } @media (min-width: 768px) { .form-inline .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } .form-inline .form-control { display: inline-block; width: auto; vertical-align: middle; } .form-inline .form-control-static { display: inline-block; } .form-inline .input-group { display: inline-table; vertical-align: middle; } .form-inline .input-group .input-group-addon, .form-inline .input-group .input-group-btn, .form-inline .input-group .form-control { width: auto; } .form-inline .input-group > .form-control { width: 100%; } .form-inline .control-label { margin-bottom: 0; vertical-align: middle; } .form-inline .radio, .form-inline .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } .form-inline .radio label, .form-inline .checkbox label { padding-left: 0; } .form-inline .radio input[type="radio"], .form-inline .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } .form-inline .has-feedback .form-control-feedback { top: 0; } } .form-horizontal .radio, .form-horizontal .checkbox, .form-horizontal .radio-inline, .form-horizontal .checkbox-inline { margin-top: 0; margin-bottom: 0; padding-top: 7px; } .form-horizontal .radio, .form-horizontal .checkbox { min-height: 34px; } .form-horizontal .form-group { margin-left: -15px; margin-right: -15px; } .form-horizontal .form-group:before, .form-horizontal .form-group:after { content: " "; display: table; } .form-horizontal .form-group:after { clear: both; } @media (min-width: 768px) { .form-horizontal .control-label { text-align: right; margin-bottom: 0; padding-top: 7px; } } .form-horizontal .has-feedback .form-control-feedback { right: 15px; } @media (min-width: 768px) { .form-horizontal .form-group-lg .control-label { padding-top: 11px; font-size: 19px; } } @media (min-width: 768px) { .form-horizontal .form-group-sm .control-label { padding-top: 6px; font-size: 13px; } } .btn { display: inline-block; margin-bottom: 0; font-weight: normal; text-align: center; vertical-align: middle; touch-action: manipulation; cursor: pointer; background-image: none; border: 1px solid transparent; white-space: nowrap; padding: 6px 16px; font-size: 15px; line-height: 1.846; border-radius: 3px; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .btn:focus, .btn.focus, .btn:active:focus, .btn:active.focus, .btn.active:focus, .btn.active.focus { outline: 5px auto -webkit-focus-ring-color; outline-offset: -2px; } .btn:hover, .btn:focus, .btn.focus { color: #444; text-decoration: none; } .btn:active, .btn.active { outline: 0; background-image: none; -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } .btn.disabled, .btn[disabled], fieldset[disabled] .btn { cursor: not-allowed; opacity: 0.65; filter: alpha(opacity=65); -webkit-box-shadow: none; box-shadow: none; } a.btn.disabled, fieldset[disabled] a.btn { pointer-events: none; } .btn-default { color: #444; background-color: #fff; border-color: transparent; } .btn-default:focus, .btn-default.focus { color: #444; background-color: #e6e6e6; border-color: rgba(0, 0, 0, 0); } .btn-default:hover { color: #444; background-color: #e6e6e6; border-color: rgba(0, 0, 0, 0); } .btn-default:active, .btn-default.active, .open > .btn-default.dropdown-toggle { color: #444; background-color: #e6e6e6; border-color: rgba(0, 0, 0, 0); } .btn-default:active:hover, .btn-default:active:focus, .btn-default:active.focus, .btn-default.active:hover, .btn-default.active:focus, .btn-default.active.focus, .open > .btn-default.dropdown-toggle:hover, .open > .btn-default.dropdown-toggle:focus, .open > .btn-default.dropdown-toggle.focus { color: #444; background-color: #d4d4d4; border-color: rgba(0, 0, 0, 0); } .btn-default:active, .btn-default.active, .open > .btn-default.dropdown-toggle { background-image: none; } .btn-default.disabled:hover, .btn-default.disabled:focus, .btn-default.disabled.focus, .btn-default[disabled]:hover, .btn-default[disabled]:focus, .btn-default[disabled].focus, fieldset[disabled] .btn-default:hover, fieldset[disabled] .btn-default:focus, fieldset[disabled] .btn-default.focus { background-color: #fff; border-color: transparent; } .btn-default .badge { color: #fff; background-color: #444; } .btn-primary { color: #fff; background-color: #5a9ddb; border-color: transparent; } .btn-primary:focus, .btn-primary.focus { color: #fff; background-color: #3084d2; border-color: rgba(0, 0, 0, 0); } .btn-primary:hover { color: #fff; background-color: #3084d2; border-color: rgba(0, 0, 0, 0); } .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle { color: #fff; background-color: #3084d2; border-color: rgba(0, 0, 0, 0); } .btn-primary:active:hover, .btn-primary:active:focus, .btn-primary:active.focus, .btn-primary.active:hover, .btn-primary.active:focus, .btn-primary.active.focus, .open > .btn-primary.dropdown-toggle:hover, .open > .btn-primary.dropdown-toggle:focus, .open > .btn-primary.dropdown-toggle.focus { color: #fff; background-color: #2872b6; border-color: rgba(0, 0, 0, 0); } .btn-primary:active, .btn-primary.active, .open > .btn-primary.dropdown-toggle { background-image: none; } .btn-primary.disabled:hover, .btn-primary.disabled:focus, .btn-primary.disabled.focus, .btn-primary[disabled]:hover, .btn-primary[disabled]:focus, .btn-primary[disabled].focus, fieldset[disabled] .btn-primary:hover, fieldset[disabled] .btn-primary:focus, fieldset[disabled] .btn-primary.focus { background-color: #5a9ddb; border-color: transparent; } .btn-primary .badge { color: #5a9ddb; background-color: #fff; } .btn-success { color: #fff; background-color: #4CAF50; border-color: transparent; } .btn-success:focus, .btn-success.focus { color: #fff; background-color: #3d8b40; border-color: rgba(0, 0, 0, 0); } .btn-success:hover { color: #fff; background-color: #3d8b40; border-color: rgba(0, 0, 0, 0); } .btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle { color: #fff; background-color: #3d8b40; border-color: rgba(0, 0, 0, 0); } .btn-success:active:hover, .btn-success:active:focus, .btn-success:active.focus, .btn-success.active:hover, .btn-success.active:focus, .btn-success.active.focus, .open > .btn-success.dropdown-toggle:hover, .open > .btn-success.dropdown-toggle:focus, .open > .btn-success.dropdown-toggle.focus { color: #fff; background-color: #327334; border-color: rgba(0, 0, 0, 0); } .btn-success:active, .btn-success.active, .open > .btn-success.dropdown-toggle { background-image: none; } .btn-success.disabled:hover, .btn-success.disabled:focus, .btn-success.disabled.focus, .btn-success[disabled]:hover, .btn-success[disabled]:focus, .btn-success[disabled].focus, fieldset[disabled] .btn-success:hover, fieldset[disabled] .btn-success:focus, fieldset[disabled] .btn-success.focus { background-color: #4CAF50; border-color: transparent; } .btn-success .badge { color: #4CAF50; background-color: #fff; } .btn-info { color: #fff; background-color: #9C27B0; border-color: transparent; } .btn-info:focus, .btn-info.focus { color: #fff; background-color: #771e86; border-color: rgba(0, 0, 0, 0); } .btn-info:hover { color: #fff; background-color: #771e86; border-color: rgba(0, 0, 0, 0); } .btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle { color: #fff; background-color: #771e86; border-color: rgba(0, 0, 0, 0); } .btn-info:active:hover, .btn-info:active:focus, .btn-info:active.focus, .btn-info.active:hover, .btn-info.active:focus, .btn-info.active.focus, .open > .btn-info.dropdown-toggle:hover, .open > .btn-info.dropdown-toggle:focus, .open > .btn-info.dropdown-toggle.focus { color: #fff; background-color: #5d1769; border-color: rgba(0, 0, 0, 0); } .btn-info:active, .btn-info.active, .open > .btn-info.dropdown-toggle { background-image: none; } .btn-info.disabled:hover, .btn-info.disabled:focus, .btn-info.disabled.focus, .btn-info[disabled]:hover, .btn-info[disabled]:focus, .btn-info[disabled].focus, fieldset[disabled] .btn-info:hover, fieldset[disabled] .btn-info:focus, fieldset[disabled] .btn-info.focus { background-color: #9C27B0; border-color: transparent; } .btn-info .badge { color: #9C27B0; background-color: #fff; } .btn-warning { color: #fff; background-color: #ff9800; border-color: transparent; } .btn-warning:focus, .btn-warning.focus { color: #fff; background-color: #cc7a00; border-color: rgba(0, 0, 0, 0); } .btn-warning:hover { color: #fff; background-color: #cc7a00; border-color: rgba(0, 0, 0, 0); } .btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle { color: #fff; background-color: #cc7a00; border-color: rgba(0, 0, 0, 0); } .btn-warning:active:hover, .btn-warning:active:focus, .btn-warning:active.focus, .btn-warning.active:hover, .btn-warning.active:focus, .btn-warning.active.focus, .open > .btn-warning.dropdown-toggle:hover, .open > .btn-warning.dropdown-toggle:focus, .open > .btn-warning.dropdown-toggle.focus { color: #fff; background-color: #a86400; border-color: rgba(0, 0, 0, 0); } .btn-warning:active, .btn-warning.active, .open > .btn-warning.dropdown-toggle { background-image: none; } .btn-warning.disabled:hover, .btn-warning.disabled:focus, .btn-warning.disabled.focus, .btn-warning[disabled]:hover, .btn-warning[disabled]:focus, .btn-warning[disabled].focus, fieldset[disabled] .btn-warning:hover, fieldset[disabled] .btn-warning:focus, fieldset[disabled] .btn-warning.focus { background-color: #ff9800; border-color: transparent; } .btn-warning .badge { color: #ff9800; background-color: #fff; } .btn-danger { color: #fff; background-color: #e51c23; border-color: transparent; } .btn-danger:focus, .btn-danger.focus { color: #fff; background-color: #b9151b; border-color: rgba(0, 0, 0, 0); } .btn-danger:hover { color: #fff; background-color: #b9151b; border-color: rgba(0, 0, 0, 0); } .btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle { color: #fff; background-color: #b9151b; border-color: rgba(0, 0, 0, 0); } .btn-danger:active:hover, .btn-danger:active:focus, .btn-danger:active.focus, .btn-danger.active:hover, .btn-danger.active:focus, .btn-danger.active.focus, .open > .btn-danger.dropdown-toggle:hover, .open > .btn-danger.dropdown-toggle:focus, .open > .btn-danger.dropdown-toggle.focus { color: #fff; background-color: #991216; border-color: rgba(0, 0, 0, 0); } .btn-danger:active, .btn-danger.active, .open > .btn-danger.dropdown-toggle { background-image: none; } .btn-danger.disabled:hover, .btn-danger.disabled:focus, .btn-danger.disabled.focus, .btn-danger[disabled]:hover, .btn-danger[disabled]:focus, .btn-danger[disabled].focus, fieldset[disabled] .btn-danger:hover, fieldset[disabled] .btn-danger:focus, fieldset[disabled] .btn-danger.focus { background-color: #e51c23; border-color: transparent; } .btn-danger .badge { color: #e51c23; background-color: #fff; } .btn-link { color: #5a9ddb; font-weight: normal; border-radius: 0; } .btn-link, .btn-link:active, .btn-link.active, .btn-link[disabled], fieldset[disabled] .btn-link { background-color: transparent; -webkit-box-shadow: none; box-shadow: none; } .btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { border-color: transparent; } .btn-link:hover, .btn-link:focus { color: #2a77bf; text-decoration: underline; background-color: transparent; } .btn-link[disabled]:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:hover, fieldset[disabled] .btn-link:focus { color: #bbb; text-decoration: none; } .btn-lg, .btn-group-lg > .btn { padding: 10px 16px; font-size: 19px; line-height: 1.3333333; border-radius: 3px; } .btn-sm, .btn-group-sm > .btn { padding: 5px 10px; font-size: 13px; line-height: 1.5; border-radius: 3px; } .btn-xs, .btn-group-xs > .btn { padding: 1px 5px; font-size: 13px; line-height: 1.5; border-radius: 3px; } .btn-block { display: block; width: 100%; } .btn-block + .btn-block { margin-top: 5px; } input[type="submit"].btn-block, input[type="reset"].btn-block, input[type="button"].btn-block { width: 100%; } .fade { opacity: 0; -webkit-transition: opacity 0.15s linear; -o-transition: opacity 0.15s linear; transition: opacity 0.15s linear; } .fade.in { opacity: 1; } .collapse { display: none; } .collapse.in { display: block; } tr.collapse.in { display: table-row; } tbody.collapse.in { display: table-row-group; } .collapsing { position: relative; height: 0; overflow: hidden; -webkit-transition-property: height, visibility; transition-property: height, visibility; -webkit-transition-duration: 0.35s; transition-duration: 0.35s; -webkit-transition-timing-function: ease; transition-timing-function: ease; } .caret { display: inline-block; width: 0; height: 0; margin-left: 2px; vertical-align: middle; border-top: 4px dashed; border-top: 4px solid \9; border-right: 4px solid transparent; border-left: 4px solid transparent; } .dropup, .dropdown { position: relative; } .dropdown-toggle:focus { outline: 0; } .dropdown-menu { position: absolute; top: 100%; left: 0; z-index: 1000; display: none; float: left; min-width: 160px; padding: 5px 0; margin: 2px 0 0; list-style: none; font-size: 15px; text-align: left; background-color: #fff; border: 1px solid #ccc; border: 1px solid rgba(0, 0, 0, 0.15); border-radius: 3px; -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); background-clip: padding-box; } .dropdown-menu.pull-right { right: 0; left: auto; } .dropdown-menu .divider { height: 1px; margin: 12.5px 0; overflow: hidden; background-color: #e5e5e5; } .dropdown-menu > li > a { display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.846; color: #444; white-space: nowrap; } .dropdown-menu > li > a:hover, .dropdown-menu > li > a:focus { text-decoration: none; color: #141414; background-color: #eeeeee; } .dropdown-menu > .active > a, .dropdown-menu > .active > a:hover, .dropdown-menu > .active > a:focus { color: #fff; text-decoration: none; outline: 0; background-color: #5a9ddb; } .dropdown-menu > .disabled > a, .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { color: #bbb; } .dropdown-menu > .disabled > a:hover, .dropdown-menu > .disabled > a:focus { text-decoration: none; background-color: transparent; background-image: none; filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); cursor: not-allowed; } .open > .dropdown-menu { display: block; } .open > a { outline: 0; } .dropdown-menu-right { left: auto; right: 0; } .dropdown-menu-left { left: 0; right: auto; } .dropdown-header { display: block; padding: 3px 20px; font-size: 13px; line-height: 1.846; color: #bbb; white-space: nowrap; } .dropdown-backdrop { position: fixed; left: 0; right: 0; bottom: 0; top: 0; z-index: 990; } .pull-right > .dropdown-menu { right: 0; left: auto; } .dropup .caret, .navbar-fixed-bottom .dropdown .caret { border-top: 0; border-bottom: 4px dashed; border-bottom: 4px solid \9; content: ""; } .dropup .dropdown-menu, .navbar-fixed-bottom .dropdown .dropdown-menu { top: auto; bottom: 100%; margin-bottom: 2px; } @media (min-width: 768px) { .navbar-right .dropdown-menu { right: 0; left: auto; } .navbar-right .dropdown-menu-left { left: 0; right: auto; } } .btn-group, .btn-group-vertical { position: relative; display: inline-block; vertical-align: middle; } .btn-group > .btn, .btn-group-vertical > .btn { position: relative; float: left; } .btn-group > .btn:hover, .btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active, .btn-group-vertical > .btn:hover, .btn-group-vertical > .btn:focus, .btn-group-vertical > .btn:active, .btn-group-vertical > .btn.active { z-index: 2; } .btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group { margin-left: -1px; } .btn-toolbar { margin-left: -5px; } .btn-toolbar:before, .btn-toolbar:after { content: " "; display: table; } .btn-toolbar:after { clear: both; } .btn-toolbar .btn, .btn-toolbar .btn-group, .btn-toolbar .input-group { float: left; } .btn-toolbar > .btn, .btn-toolbar > .btn-group, .btn-toolbar > .input-group { margin-left: 5px; } .btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) { border-radius: 0; } .btn-group > .btn:first-child { margin-left: 0; } .btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) { border-bottom-right-radius: 0; border-top-right-radius: 0; } .btn-group > .btn:last-child:not(:first-child), .btn-group > .dropdown-toggle:not(:first-child) { border-bottom-left-radius: 0; border-top-left-radius: 0; } .btn-group > .btn-group { float: left; } .btn-group > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-top-right-radius: 0; } .btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child { border-bottom-left-radius: 0; border-top-left-radius: 0; } .btn-group .dropdown-toggle:active, .btn-group.open .dropdown-toggle { outline: 0; } .btn-group > .btn + .dropdown-toggle { padding-left: 8px; padding-right: 8px; } .btn-group > .btn-lg + .dropdown-toggle, .btn-group-lg.btn-group > .btn + .dropdown-toggle { padding-left: 12px; padding-right: 12px; } .btn-group.open .dropdown-toggle { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); } .btn-group.open .dropdown-toggle.btn-link { -webkit-box-shadow: none; box-shadow: none; } .btn .caret { margin-left: 0; } .btn-lg .caret, .btn-group-lg > .btn .caret { border-width: 5px 5px 0; border-bottom-width: 0; } .dropup .btn-lg .caret, .dropup .btn-group-lg > .btn .caret { border-width: 0 5px 5px; } .btn-group-vertical > .btn, .btn-group-vertical > .btn-group, .btn-group-vertical > .btn-group > .btn { display: block; float: none; width: 100%; max-width: 100%; } .btn-group-vertical > .btn-group:before, .btn-group-vertical > .btn-group:after { content: " "; display: table; } .btn-group-vertical > .btn-group:after { clear: both; } .btn-group-vertical > .btn-group > .btn { float: none; } .btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { margin-top: -1px; margin-left: 0; } .btn-group-vertical > .btn:not(:first-child):not(:last-child) { border-radius: 0; } .btn-group-vertical > .btn:first-child:not(:last-child) { border-top-right-radius: 3px; border-top-left-radius: 3px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn:last-child:not(:first-child) { border-top-right-radius: 0; border-top-left-radius: 0; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } .btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn { border-radius: 0; } .btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child, .btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle { border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child { border-top-right-radius: 0; border-top-left-radius: 0; } .btn-group-justified { display: table; width: 100%; table-layout: fixed; border-collapse: separate; } .btn-group-justified > .btn, .btn-group-justified > .btn-group { float: none; display: table-cell; width: 1%; } .btn-group-justified > .btn-group .btn { width: 100%; } .btn-group-justified > .btn-group .dropdown-menu { left: auto; } [data-toggle="buttons"] > .btn input[type="radio"], [data-toggle="buttons"] > .btn input[type="checkbox"], [data-toggle="buttons"] > .btn-group > .btn input[type="radio"], [data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] { position: absolute; clip: rect(0, 0, 0, 0); pointer-events: none; } .input-group { position: relative; display: table; border-collapse: separate; } .input-group[class*="col-"] { float: none; padding-left: 0; padding-right: 0; } .input-group .form-control { position: relative; z-index: 2; float: left; width: 100%; margin-bottom: 0; } .input-group .form-control:focus { z-index: 3; } .input-group-addon, .input-group-btn, .input-group .form-control { display: table-cell; } .input-group-addon:not(:first-child):not(:last-child), .input-group-btn:not(:first-child):not(:last-child), .input-group .form-control:not(:first-child):not(:last-child) { border-radius: 0; } .input-group-addon, .input-group-btn { width: 1%; white-space: nowrap; vertical-align: middle; } .input-group-addon { padding: 6px 16px; font-size: 15px; font-weight: normal; line-height: 1; color: #666; text-align: center; background-color: transparent; border: 1px solid transparent; border-radius: 3px; } .input-group-addon.input-sm, .input-group-sm > .input-group-addon, .input-group-sm > .input-group-btn > .input-group-addon.btn { padding: 5px 10px; font-size: 13px; border-radius: 3px; } .input-group-addon.input-lg, .input-group-lg > .input-group-addon, .input-group-lg > .input-group-btn > .input-group-addon.btn { padding: 10px 16px; font-size: 19px; border-radius: 3px; } .input-group-addon input[type="radio"], .input-group-addon input[type="checkbox"] { margin-top: 0; } .input-group .form-control:first-child, .input-group-addon:first-child, .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group > .btn, .input-group-btn:first-child > .dropdown-toggle, .input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle), .input-group-btn:last-child > .btn-group:not(:last-child) > .btn { border-bottom-right-radius: 0; border-top-right-radius: 0; } .input-group-addon:first-child { border-right: 0; } .input-group .form-control:last-child, .input-group-addon:last-child, .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group > .btn, .input-group-btn:last-child > .dropdown-toggle, .input-group-btn:first-child > .btn:not(:first-child), .input-group-btn:first-child > .btn-group:not(:first-child) > .btn { border-bottom-left-radius: 0; border-top-left-radius: 0; } .input-group-addon:last-child { border-left: 0; } .input-group-btn { position: relative; font-size: 0; white-space: nowrap; } .input-group-btn > .btn { position: relative; } .input-group-btn > .btn + .btn { margin-left: -1px; } .input-group-btn > .btn:hover, .input-group-btn > .btn:focus, .input-group-btn > .btn:active { z-index: 2; } .input-group-btn:first-child > .btn, .input-group-btn:first-child > .btn-group { margin-right: -1px; } .input-group-btn:last-child > .btn, .input-group-btn:last-child > .btn-group { z-index: 2; margin-left: -1px; } .nav { margin-bottom: 0; padding-left: 0; list-style: none; } .nav:before, .nav:after { content: " "; display: table; } .nav:after { clear: both; } .nav > li { position: relative; display: block; } .nav > li > a { position: relative; display: block; padding: 10px 15px; } .nav > li > a:hover, .nav > li > a:focus { text-decoration: none; background-color: #eeeeee; } .nav > li.disabled > a { color: #bbb; } .nav > li.disabled > a:hover, .nav > li.disabled > a:focus { color: #bbb; text-decoration: none; background-color: transparent; cursor: not-allowed; } .nav .open > a, .nav .open > a:hover, .nav .open > a:focus { background-color: #eeeeee; border-color: #5a9ddb; } .nav .nav-divider { height: 1px; margin: 12.5px 0; overflow: hidden; background-color: #e5e5e5; } .nav > li > a > img { max-width: none; } .nav-tabs { border-bottom: 1px solid transparent; } .nav-tabs > li { float: left; margin-bottom: -1px; } .nav-tabs > li > a { margin-right: 2px; line-height: 1.846; border: 1px solid transparent; border-radius: 3px 3px 0 0; } .nav-tabs > li > a:hover { border-color: #eeeeee #eeeeee transparent; } .nav-tabs > li.active > a, .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus { color: #666; background-color: transparent; border: 1px solid transparent; border-bottom-color: transparent; cursor: default; } .nav-pills > li { float: left; } .nav-pills > li > a { border-radius: 3px; } .nav-pills > li + li { margin-left: 2px; } .nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus { color: #fff; background-color: #5a9ddb; } .nav-stacked > li { float: none; } .nav-stacked > li + li { margin-top: 2px; margin-left: 0; } .nav-justified, .nav-tabs.nav-justified { width: 100%; } .nav-justified > li, .nav-tabs.nav-justified > li { float: none; } .nav-justified > li > a, .nav-tabs.nav-justified > li > a { text-align: center; margin-bottom: 5px; } .nav-justified > .dropdown .dropdown-menu { top: auto; left: auto; } @media (min-width: 768px) { .nav-justified > li, .nav-tabs.nav-justified > li { display: table-cell; width: 1%; } .nav-justified > li > a, .nav-tabs.nav-justified > li > a { margin-bottom: 0; } } .nav-tabs-justified, .nav-tabs.nav-justified { border-bottom: 0; } .nav-tabs-justified > li > a, .nav-tabs.nav-justified > li > a { margin-right: 0; border-radius: 3px; } .nav-tabs-justified > .active > a, .nav-tabs.nav-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus, .nav-tabs.nav-justified > .active > a:focus { border: 1px solid transparent; } @media (min-width: 768px) { .nav-tabs-justified > li > a, .nav-tabs.nav-justified > li > a { border-bottom: 1px solid transparent; border-radius: 3px 3px 0 0; } .nav-tabs-justified > .active > a, .nav-tabs.nav-justified > .active > a, .nav-tabs-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs-justified > .active > a:focus, .nav-tabs.nav-justified > .active > a:focus { border-bottom-color: #fff; } } .tab-content > .tab-pane { display: none; } .tab-content > .active { display: block; } .nav-tabs .dropdown-menu { margin-top: -1px; border-top-right-radius: 0; border-top-left-radius: 0; } .navbar { position: relative; min-height: 110px; margin-bottom: 27px; border: 1px solid transparent; } .navbar:before, .navbar:after { content: " "; display: table; } .navbar:after { clear: both; } @media (min-width: 768px) { .navbar { border-radius: 3px; } } .navbar-header:before, .navbar-header:after { content: " "; display: table; } .navbar-header:after { clear: both; } @media (min-width: 768px) { .navbar-header { float: left; } } .navbar-collapse { overflow-x: visible; padding-right: 15px; padding-left: 15px; border-top: 1px solid transparent; box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1); -webkit-overflow-scrolling: touch; } .navbar-collapse:before, .navbar-collapse:after { content: " "; display: table; } .navbar-collapse:after { clear: both; } .navbar-collapse.in { overflow-y: auto; } @media (min-width: 768px) { .navbar-collapse { width: auto; border-top: 0; box-shadow: none; } .navbar-collapse.collapse { display: block !important; height: auto !important; padding-bottom: 0; overflow: visible !important; } .navbar-collapse.in { overflow-y: visible; } .navbar-fixed-top .navbar-collapse, .navbar-static-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { padding-left: 0; padding-right: 0; } } .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { max-height: 340px; } @media (max-device-width: 480px) and (orientation: landscape) { .navbar-fixed-top .navbar-collapse, .navbar-fixed-bottom .navbar-collapse { max-height: 200px; } } .container > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-header, .container-fluid > .navbar-collapse { margin-right: -15px; margin-left: -15px; } @media (min-width: 768px) { .container > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-header, .container-fluid > .navbar-collapse { margin-right: 0; margin-left: 0; } } .navbar-static-top { z-index: 1000; border-width: 0 0 1px; } @media (min-width: 768px) { .navbar-static-top { border-radius: 0; } } .navbar-fixed-top, .navbar-fixed-bottom { position: fixed; right: 0; left: 0; z-index: 1030; } @media (min-width: 768px) { .navbar-fixed-top, .navbar-fixed-bottom { border-radius: 0; } } .navbar-fixed-top { top: 0; border-width: 0 0 1px; } .navbar-fixed-bottom { bottom: 0; margin-bottom: 0; border-width: 1px 0 0; } .navbar-brand { float: left; padding: 41.5px 15px; font-size: 19px; line-height: 27px; height: 110px; } .navbar-brand:hover, .navbar-brand:focus { text-decoration: none; } .navbar-brand > img { display: block; } @media (min-width: 768px) { .navbar > .container .navbar-brand, .navbar > .container-fluid .navbar-brand { margin-left: -15px; } } .navbar-toggle { position: relative; float: right; margin-right: 15px; padding: 9px 10px; margin-top: 38px; margin-bottom: 38px; background-color: transparent; background-image: none; border: 1px solid transparent; border-radius: 3px; } .navbar-toggle:focus { outline: 0; } .navbar-toggle .icon-bar { display: block; width: 22px; height: 2px; border-radius: 1px; } .navbar-toggle .icon-bar + .icon-bar { margin-top: 4px; } @media (min-width: 768px) { .navbar-toggle { display: none; } } .navbar-nav { margin: 20.75px -15px; } .navbar-nav > li > a { padding-top: 10px; padding-bottom: 10px; line-height: 27px; } @media (max-width: 767px) { .navbar-nav .open .dropdown-menu { position: static; float: none; width: auto; margin-top: 0; background-color: transparent; border: 0; box-shadow: none; } .navbar-nav .open .dropdown-menu > li > a, .navbar-nav .open .dropdown-menu .dropdown-header { padding: 5px 15px 5px 25px; } .navbar-nav .open .dropdown-menu > li > a { line-height: 27px; } .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-nav .open .dropdown-menu > li > a:focus { background-image: none; } } @media (min-width: 768px) { .navbar-nav { float: left; margin: 0; } .navbar-nav > li { float: left; } .navbar-nav > li > a { padding-top: 41.5px; padding-bottom: 41.5px; } } .navbar-form { margin-left: -15px; margin-right: -15px; padding: 10px 15px; border-top: 1px solid transparent; border-bottom: 1px solid transparent; -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1); margin-top: 34.5px; margin-bottom: 34.5px; } @media (min-width: 768px) { .navbar-form .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; } .navbar-form .form-control { display: inline-block; width: auto; vertical-align: middle; } .navbar-form .form-control-static { display: inline-block; } .navbar-form .input-group { display: inline-table; vertical-align: middle; } .navbar-form .input-group .input-group-addon, .navbar-form .input-group .input-group-btn, .navbar-form .input-group .form-control { width: auto; } .navbar-form .input-group > .form-control { width: 100%; } .navbar-form .control-label { margin-bottom: 0; vertical-align: middle; } .navbar-form .radio, .navbar-form .checkbox { display: inline-block; margin-top: 0; margin-bottom: 0; vertical-align: middle; } .navbar-form .radio label, .navbar-form .checkbox label { padding-left: 0; } .navbar-form .radio input[type="radio"], .navbar-form .checkbox input[type="checkbox"] { position: relative; margin-left: 0; } .navbar-form .has-feedback .form-control-feedback { top: 0; } } @media (max-width: 767px) { .navbar-form .form-group { margin-bottom: 5px; } .navbar-form .form-group:last-child { margin-bottom: 0; } } @media (min-width: 768px) { .navbar-form { width: auto; border: 0; margin-left: 0; margin-right: 0; padding-top: 0; padding-bottom: 0; -webkit-box-shadow: none; box-shadow: none; } } .navbar-nav > li > .dropdown-menu { margin-top: 0; border-top-right-radius: 0; border-top-left-radius: 0; } .navbar-fixed-bottom .navbar-nav > li > .dropdown-menu { margin-bottom: 0; border-top-right-radius: 3px; border-top-left-radius: 3px; border-bottom-right-radius: 0; border-bottom-left-radius: 0; } .navbar-btn { margin-top: 34.5px; margin-bottom: 34.5px; } .navbar-btn.btn-sm, .btn-group-sm > .navbar-btn.btn { margin-top: 39.5px; margin-bottom: 39.5px; } .navbar-btn.btn-xs, .btn-group-xs > .navbar-btn.btn { margin-top: 44px; margin-bottom: 44px; } .navbar-text { margin-top: 41.5px; margin-bottom: 41.5px; } @media (min-width: 768px) { .navbar-text { float: left; margin-left: 15px; margin-right: 15px; } } @media (min-width: 768px) { .navbar-left { float: left !important; } .navbar-right { float: right !important; margin-right: -15px; } .navbar-right ~ .navbar-right { margin-right: 0; } } .navbar-default { background-color: #fff; border-color: transparent; } .navbar-default .navbar-brand { color: #444; } .navbar-default .navbar-brand:hover, .navbar-default .navbar-brand:focus { color: #222; background-color: transparent; } .navbar-default .navbar-text { color: #bbb; } .navbar-default .navbar-nav > li > a { color: #444; } .navbar-default .navbar-nav > li > a:hover, .navbar-default .navbar-nav > li > a:focus { color: #222; background-color: transparent; } .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { color: #212121; background-color: #fcfcfc; } .navbar-default .navbar-nav > .disabled > a, .navbar-default .navbar-nav > .disabled > a:hover, .navbar-default .navbar-nav > .disabled > a:focus { color: #ccc; background-color: transparent; } .navbar-default .navbar-toggle { border-color: transparent; } .navbar-default .navbar-toggle:hover, .navbar-default .navbar-toggle:focus { background-color: transparent; } .navbar-default .navbar-toggle .icon-bar { background-color: rgba(0, 0, 0, 0.5); } .navbar-default .navbar-collapse, .navbar-default .navbar-form { border-color: transparent; } .navbar-default .navbar-nav > .open > a, .navbar-default .navbar-nav > .open > a:hover, .navbar-default .navbar-nav > .open > a:focus { background-color: #fcfcfc; color: #212121; } @media (max-width: 767px) { .navbar-default .navbar-nav .open .dropdown-menu > li > a { color: #444; } .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus { color: #222; background-color: transparent; } .navbar-default .navbar-nav .open .dropdown-menu > .active > a, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus { color: #212121; background-color: #fcfcfc; } .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #ccc; background-color: transparent; } } .navbar-default .navbar-link { color: #444; } .navbar-default .navbar-link:hover { color: #222; } .navbar-default .btn-link { color: #444; } .navbar-default .btn-link:hover, .navbar-default .btn-link:focus { color: #222; } .navbar-default .btn-link[disabled]:hover, .navbar-default .btn-link[disabled]:focus, fieldset[disabled] .navbar-default .btn-link:hover, fieldset[disabled] .navbar-default .btn-link:focus { color: #ccc; } .navbar-inverse { background-color: #5a9ddb; border-color: transparent; } .navbar-inverse .navbar-brand { color: #d8e8f6; } .navbar-inverse .navbar-brand:hover, .navbar-inverse .navbar-brand:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-text { color: #bbb; } .navbar-inverse .navbar-nav > li > a { color: #d8e8f6; } .navbar-inverse .navbar-nav > li > a:hover, .navbar-inverse .navbar-nav > li > a:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav > .active > a, .navbar-inverse .navbar-nav > .active > a:hover, .navbar-inverse .navbar-nav > .active > a:focus { color: #fff; background-color: #3084d2; } .navbar-inverse .navbar-nav > .disabled > a, .navbar-inverse .navbar-nav > .disabled > a:hover, .navbar-inverse .navbar-nav > .disabled > a:focus { color: #444; background-color: transparent; } .navbar-inverse .navbar-toggle { border-color: transparent; } .navbar-inverse .navbar-toggle:hover, .navbar-inverse .navbar-toggle:focus { background-color: transparent; } .navbar-inverse .navbar-toggle .icon-bar { background-color: rgba(0, 0, 0, 0.5); } .navbar-inverse .navbar-collapse, .navbar-inverse .navbar-form { border-color: #3d8cd5; } .navbar-inverse .navbar-nav > .open > a, .navbar-inverse .navbar-nav > .open > a:hover, .navbar-inverse .navbar-nav > .open > a:focus { background-color: #3084d2; color: #fff; } @media (max-width: 767px) { .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header { border-color: transparent; } .navbar-inverse .navbar-nav .open .dropdown-menu .divider { background-color: transparent; } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a { color: #d8e8f6; } .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus { color: #fff; background-color: transparent; } .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus { color: #fff; background-color: #3084d2; } .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover, .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus { color: #444; background-color: transparent; } } .navbar-inverse .navbar-link { color: #d8e8f6; } .navbar-inverse .navbar-link:hover { color: #fff; } .navbar-inverse .btn-link { color: #d8e8f6; } .navbar-inverse .btn-link:hover, .navbar-inverse .btn-link:focus { color: #fff; } .navbar-inverse .btn-link[disabled]:hover, .navbar-inverse .btn-link[disabled]:focus, fieldset[disabled] .navbar-inverse .btn-link:hover, fieldset[disabled] .navbar-inverse .btn-link:focus { color: #444; } .breadcrumb { padding: 8px 15px; margin-bottom: 27px; list-style: none; background-color: #f5f5f5; border-radius: 3px; } .breadcrumb > li { display: inline-block; } .breadcrumb > li + li:before { content: "/ "; padding: 0 5px; color: #ccc; } .breadcrumb > .active { color: #bbb; } .pagination { display: inline-block; padding-left: 0; margin: 27px 0; border-radius: 3px; } .pagination > li { display: inline; } .pagination > li > a, .pagination > li > span { position: relative; float: left; padding: 6px 16px; line-height: 1.846; text-decoration: none; color: #5a9ddb; background-color: #fff; border: 1px solid #ddd; margin-left: -1px; } .pagination > li:first-child > a, .pagination > li:first-child > span { margin-left: 0; border-bottom-left-radius: 3px; border-top-left-radius: 3px; } .pagination > li:last-child > a, .pagination > li:last-child > span { border-bottom-right-radius: 3px; border-top-right-radius: 3px; } .pagination > li > a:hover, .pagination > li > a:focus, .pagination > li > span:hover, .pagination > li > span:focus { z-index: 2; color: #2a77bf; background-color: #eeeeee; border-color: #ddd; } .pagination > .active > a, .pagination > .active > a:hover, .pagination > .active > a:focus, .pagination > .active > span, .pagination > .active > span:hover, .pagination > .active > span:focus { z-index: 3; color: #fff; background-color: #5a9ddb; border-color: #5a9ddb; cursor: default; } .pagination > .disabled > span, .pagination > .disabled > span:hover, .pagination > .disabled > span:focus, .pagination > .disabled > a, .pagination > .disabled > a:hover, .pagination > .disabled > a:focus { color: #bbb; background-color: #fff; border-color: #ddd; cursor: not-allowed; } .pagination-lg > li > a, .pagination-lg > li > span { padding: 10px 16px; font-size: 19px; line-height: 1.3333333; } .pagination-lg > li:first-child > a, .pagination-lg > li:first-child > span { border-bottom-left-radius: 3px; border-top-left-radius: 3px; } .pagination-lg > li:last-child > a, .pagination-lg > li:last-child > span { border-bottom-right-radius: 3px; border-top-right-radius: 3px; } .pagination-sm > li > a, .pagination-sm > li > span { padding: 5px 10px; font-size: 13px; line-height: 1.5; } .pagination-sm > li:first-child > a, .pagination-sm > li:first-child > span { border-bottom-left-radius: 3px; border-top-left-radius: 3px; } .pagination-sm > li:last-child > a, .pagination-sm > li:last-child > span { border-bottom-right-radius: 3px; border-top-right-radius: 3px; } .pager { padding-left: 0; margin: 27px 0; list-style: none; text-align: center; } .pager:before, .pager:after { content: " "; display: table; } .pager:after { clear: both; } .pager li { display: inline; } .pager li > a, .pager li > span { display: inline-block; padding: 5px 14px; background-color: #fff; border: 1px solid #ddd; border-radius: 15px; } .pager li > a:hover, .pager li > a:focus { text-decoration: none; background-color: #eeeeee; } .pager .next > a, .pager .next > span { float: right; } .pager .previous > a, .pager .previous > span { float: left; } .pager .disabled > a, .pager .disabled > a:hover, .pager .disabled > a:focus, .pager .disabled > span { color: #bbb; background-color: #fff; cursor: not-allowed; } .label { display: inline; padding: .2em .6em .3em; font-size: 75%; font-weight: bold; line-height: 1; color: #fff; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25em; } .label:empty { display: none; } .btn .label { position: relative; top: -1px; } a.label:hover, a.label:focus { color: #fff; text-decoration: none; cursor: pointer; } .label-default { background-color: #bbb; } .label-default[href]:hover, .label-default[href]:focus { background-color: #a2a2a2; } .label-primary { background-color: #5a9ddb; } .label-primary[href]:hover, .label-primary[href]:focus { background-color: #3084d2; } .label-success { background-color: #4CAF50; } .label-success[href]:hover, .label-success[href]:focus { background-color: #3d8b40; } .label-info { background-color: #9C27B0; } .label-info[href]:hover, .label-info[href]:focus { background-color: #771e86; } .label-warning { background-color: #ff9800; } .label-warning[href]:hover, .label-warning[href]:focus { background-color: #cc7a00; } .label-danger { background-color: #e51c23; } .label-danger[href]:hover, .label-danger[href]:focus { background-color: #b9151b; } .badge { display: inline-block; min-width: 10px; padding: 3px 7px; font-size: 13px; font-weight: normal; color: #fff; line-height: 1; vertical-align: middle; white-space: nowrap; text-align: center; background-color: #bbb; border-radius: 10px; } .badge:empty { display: none; } .btn .badge { position: relative; top: -1px; } .btn-xs .badge, .btn-group-xs > .btn .badge, .btn-group-xs > .btn .badge { top: 0; padding: 1px 5px; } .list-group-item.active > .badge, .nav-pills > .active > a > .badge { color: #5a9ddb; background-color: #fff; } .list-group-item > .badge { float: right; } .list-group-item > .badge + .badge { margin-right: 5px; } .nav-pills > li > a > .badge { margin-left: 3px; } a.badge:hover, a.badge:focus { color: #fff; text-decoration: none; cursor: pointer; } .jumbotron { padding-top: 30px; padding-bottom: 30px; margin-bottom: 30px; color: inherit; background-color: #f5f5f5; } .jumbotron h1, .jumbotron .h1 { color: #444; } .jumbotron p { margin-bottom: 15px; font-size: 23px; font-weight: 200; } .jumbotron > hr { border-top-color: gainsboro; } .container .jumbotron, .container-fluid .jumbotron { border-radius: 3px; padding-left: 15px; padding-right: 15px; } .jumbotron .container { max-width: 100%; } @media screen and (min-width: 768px) { .jumbotron { padding-top: 48px; padding-bottom: 48px; } .container .jumbotron, .container-fluid .jumbotron { padding-left: 60px; padding-right: 60px; } .jumbotron h1, .jumbotron .h1 { font-size: 68px; } } .thumbnail { display: block; padding: 4px; margin-bottom: 27px; line-height: 1.846; background-color: #fff; border: 1px solid #ddd; border-radius: 3px; -webkit-transition: border 0.2s ease-in-out; -o-transition: border 0.2s ease-in-out; transition: border 0.2s ease-in-out; } .thumbnail > img, .thumbnail a > img { display: block; max-width: 100%; height: auto; margin-left: auto; margin-right: auto; } .thumbnail .caption { padding: 9px; color: #444; } a.thumbnail:hover, a.thumbnail:focus, a.thumbnail.active { border-color: #5a9ddb; } .alert { padding: 15px; margin-bottom: 27px; border: 1px solid transparent; border-radius: 3px; } .alert h4 { margin-top: 0; color: inherit; } .alert .alert-link { font-weight: bold; } .alert > p, .alert > ul { margin-bottom: 0; } .alert > p + p { margin-top: 5px; } .alert-dismissable, .alert-dismissible { padding-right: 35px; } .alert-dismissable .close, .alert-dismissible .close { position: relative; top: -2px; right: -21px; color: inherit; } .alert-success { background-color: #dff0d8; border-color: #d6e9c6; color: #4CAF50; } .alert-success hr { border-top-color: #c9e2b3; } .alert-success .alert-link { color: #3d8b40; } .alert-info { background-color: #e1bee7; border-color: #cba4dd; color: #9C27B0; } .alert-info hr { border-top-color: #c191d6; } .alert-info .alert-link { color: #771e86; } .alert-warning { background-color: #ffe0b2; border-color: #ffc599; color: #ff9800; } .alert-warning hr { border-top-color: #ffb67f; } .alert-warning .alert-link { color: #cc7a00; } .alert-danger { background-color: #f9bdbb; border-color: #f7a4af; color: #e51c23; } .alert-danger hr { border-top-color: #f58c9a; } .alert-danger .alert-link { color: #b9151b; } @-webkit-keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } @keyframes progress-bar-stripes { from { background-position: 40px 0; } to { background-position: 0 0; } } .progress { overflow: hidden; height: 27px; margin-bottom: 27px; background-color: #f5f5f5; border-radius: 3px; -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1); } .progress-bar { float: left; width: 0%; height: 100%; font-size: 13px; line-height: 27px; color: #fff; text-align: center; background-color: #5a9ddb; -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15); -webkit-transition: width 0.6s ease; -o-transition: width 0.6s ease; transition: width 0.6s ease; } .progress-striped .progress-bar, .progress-bar-striped { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-size: 40px 40px; } .progress.active .progress-bar, .progress-bar.active { -webkit-animation: progress-bar-stripes 2s linear infinite; -o-animation: progress-bar-stripes 2s linear infinite; animation: progress-bar-stripes 2s linear infinite; } .progress-bar-success { background-color: #4CAF50; } .progress-striped .progress-bar-success { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-bar-info { background-color: #9C27B0; } .progress-striped .progress-bar-info { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-bar-warning { background-color: #ff9800; } .progress-striped .progress-bar-warning { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .progress-bar-danger { background-color: #e51c23; } .progress-striped .progress-bar-danger { background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent); } .media { margin-top: 15px; } .media:first-child { margin-top: 0; } .media, .media-body { zoom: 1; overflow: hidden; } .media-body { width: 10000px; } .media-object { display: block; } .media-object.img-thumbnail { max-width: none; } .media-right, .media > .pull-right { padding-left: 10px; } .media-left, .media > .pull-left { padding-right: 10px; } .media-left, .media-right, .media-body { display: table-cell; vertical-align: top; } .media-middle { vertical-align: middle; } .media-bottom { vertical-align: bottom; } .media-heading { margin-top: 0; margin-bottom: 5px; } .media-list { padding-left: 0; list-style: none; } .list-group { margin-bottom: 20px; padding-left: 0; } .list-group-item { position: relative; display: block; padding: 10px 15px; margin-bottom: -1px; background-color: #fff; border: 1px solid #ddd; } .list-group-item:first-child { border-top-right-radius: 3px; border-top-left-radius: 3px; } .list-group-item:last-child { margin-bottom: 0; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; } a.list-group-item, button.list-group-item { color: #555; } a.list-group-item .list-group-item-heading, button.list-group-item .list-group-item-heading { color: #333; } a.list-group-item:hover, a.list-group-item:focus, button.list-group-item:hover, button.list-group-item:focus { text-decoration: none; color: #555; background-color: #f5f5f5; } button.list-group-item { width: 100%; text-align: left; } .list-group-item.disabled, .list-group-item.disabled:hover, .list-group-item.disabled:focus { background-color: #eeeeee; color: #bbb; cursor: not-allowed; } .list-group-item.disabled .list-group-item-heading, .list-group-item.disabled:hover .list-group-item-heading, .list-group-item.disabled:focus .list-group-item-heading { color: inherit; } .list-group-item.disabled .list-group-item-text, .list-group-item.disabled:hover .list-group-item-text, .list-group-item.disabled:focus .list-group-item-text { color: #bbb; } .list-group-item.active, .list-group-item.active:hover, .list-group-item.active:focus { z-index: 2; color: #fff; background-color: #5a9ddb; border-color: #5a9ddb; } .list-group-item.active .list-group-item-heading, .list-group-item.active .list-group-item-heading > small, .list-group-item.active .list-group-item-heading > .small, .list-group-item.active:hover .list-group-item-heading, .list-group-item.active:hover .list-group-item-heading > small, .list-group-item.active:hover .list-group-item-heading > .small, .list-group-item.active:focus .list-group-item-heading, .list-group-item.active:focus .list-group-item-heading > small, .list-group-item.active:focus .list-group-item-heading > .small { color: inherit; } .list-group-item.active .list-group-item-text, .list-group-item.active:hover .list-group-item-text, .list-group-item.active:focus .list-group-item-text { color: white; } .list-group-item-success { color: #4CAF50; background-color: #dff0d8; } a.list-group-item-success, button.list-group-item-success { color: #4CAF50; } a.list-group-item-success .list-group-item-heading, button.list-group-item-success .list-group-item-heading { color: inherit; } a.list-group-item-success:hover, a.list-group-item-success:focus, button.list-group-item-success:hover, button.list-group-item-success:focus { color: #4CAF50; background-color: #d0e9c6; } a.list-group-item-success.active, a.list-group-item-success.active:hover, a.list-group-item-success.active:focus, button.list-group-item-success.active, button.list-group-item-success.active:hover, button.list-group-item-success.active:focus { color: #fff; background-color: #4CAF50; border-color: #4CAF50; } .list-group-item-info { color: #9C27B0; background-color: #e1bee7; } a.list-group-item-info, button.list-group-item-info { color: #9C27B0; } a.list-group-item-info .list-group-item-heading, button.list-group-item-info .list-group-item-heading { color: inherit; } a.list-group-item-info:hover, a.list-group-item-info:focus, button.list-group-item-info:hover, button.list-group-item-info:focus { color: #9C27B0; background-color: #d8abe0; } a.list-group-item-info.active, a.list-group-item-info.active:hover, a.list-group-item-info.active:focus, button.list-group-item-info.active, button.list-group-item-info.active:hover, button.list-group-item-info.active:focus { color: #fff; background-color: #9C27B0; border-color: #9C27B0; } .list-group-item-warning { color: #ff9800; background-color: #ffe0b2; } a.list-group-item-warning, button.list-group-item-warning { color: #ff9800; } a.list-group-item-warning .list-group-item-heading, button.list-group-item-warning .list-group-item-heading { color: inherit; } a.list-group-item-warning:hover, a.list-group-item-warning:focus, button.list-group-item-warning:hover, button.list-group-item-warning:focus { color: #ff9800; background-color: #ffd699; } a.list-group-item-warning.active, a.list-group-item-warning.active:hover, a.list-group-item-warning.active:focus, button.list-group-item-warning.active, button.list-group-item-warning.active:hover, button.list-group-item-warning.active:focus { color: #fff; background-color: #ff9800; border-color: #ff9800; } .list-group-item-danger { color: #e51c23; background-color: #f9bdbb; } a.list-group-item-danger, button.list-group-item-danger { color: #e51c23; } a.list-group-item-danger .list-group-item-heading, button.list-group-item-danger .list-group-item-heading { color: inherit; } a.list-group-item-danger:hover, a.list-group-item-danger:focus, button.list-group-item-danger:hover, button.list-group-item-danger:focus { color: #e51c23; background-color: #f7a6a4; } a.list-group-item-danger.active, a.list-group-item-danger.active:hover, a.list-group-item-danger.active:focus, button.list-group-item-danger.active, button.list-group-item-danger.active:hover, button.list-group-item-danger.active:focus { color: #fff; background-color: #e51c23; border-color: #e51c23; } .list-group-item-heading { margin-top: 0; margin-bottom: 5px; } .list-group-item-text { margin-bottom: 0; line-height: 1.3; } .panel { margin-bottom: 27px; background-color: #fff; border: 1px solid transparent; border-radius: 3px; -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05); } .panel-body { padding: 15px; } .panel-body:before, .panel-body:after { content: " "; display: table; } .panel-body:after { clear: both; } .panel-heading { padding: 10px 15px; border-bottom: 1px solid transparent; border-top-right-radius: 2px; border-top-left-radius: 2px; } .panel-heading > .dropdown .dropdown-toggle { color: inherit; } .panel-title { margin-top: 0; margin-bottom: 0; font-size: 17px; color: inherit; } .panel-title > a, .panel-title > small, .panel-title > .small, .panel-title > small > a, .panel-title > .small > a { color: inherit; } .panel-footer { padding: 10px 15px; background-color: #f5f5f5; border-top: 1px solid #ddd; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; } .panel > .list-group, .panel > .panel-collapse > .list-group { margin-bottom: 0; } .panel > .list-group .list-group-item, .panel > .panel-collapse > .list-group .list-group-item { border-width: 1px 0; border-radius: 0; } .panel > .list-group:first-child .list-group-item:first-child, .panel > .panel-collapse > .list-group:first-child .list-group-item:first-child { border-top: 0; border-top-right-radius: 2px; border-top-left-radius: 2px; } .panel > .list-group:last-child .list-group-item:last-child, .panel > .panel-collapse > .list-group:last-child .list-group-item:last-child { border-bottom: 0; border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; } .panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child { border-top-right-radius: 0; border-top-left-radius: 0; } .panel-heading + .list-group .list-group-item:first-child { border-top-width: 0; } .list-group + .panel-footer { border-top-width: 0; } .panel > .table, .panel > .table-responsive > .table, .panel > .panel-collapse > .table { margin-bottom: 0; } .panel > .table caption, .panel > .table-responsive > .table caption, .panel > .panel-collapse > .table caption { padding-left: 15px; padding-right: 15px; } .panel > .table:first-child, .panel > .table-responsive:first-child > .table:first-child { border-top-right-radius: 2px; border-top-left-radius: 2px; } .panel > .table:first-child > thead:first-child > tr:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child { border-top-left-radius: 2px; border-top-right-radius: 2px; } .panel > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child { border-top-left-radius: 2px; } .panel > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table:first-child > tbody:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child, .panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child { border-top-right-radius: 2px; } .panel > .table:last-child, .panel > .table-responsive:last-child > .table:last-child { border-bottom-right-radius: 2px; border-bottom-left-radius: 2px; } .panel > .table:last-child > tbody:last-child > tr:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child { border-bottom-left-radius: 2px; border-bottom-right-radius: 2px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child { border-bottom-left-radius: 2px; } .panel > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child, .panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child { border-bottom-right-radius: 2px; } .panel > .panel-body + .table, .panel > .panel-body + .table-responsive, .panel > .table + .panel-body, .panel > .table-responsive + .panel-body { border-top: 1px solid #ddd; } .panel > .table > tbody:first-child > tr:first-child th, .panel > .table > tbody:first-child > tr:first-child td { border-top: 0; } .panel > .table-bordered, .panel > .table-responsive > .table-bordered { border: 0; } .panel > .table-bordered > thead > tr > th:first-child, .panel > .table-bordered > thead > tr > td:first-child, .panel > .table-bordered > tbody > tr > th:first-child, .panel > .table-bordered > tbody > tr > td:first-child, .panel > .table-bordered > tfoot > tr > th:first-child, .panel > .table-bordered > tfoot > tr > td:first-child, .panel > .table-responsive > .table-bordered > thead > tr > th:first-child, .panel > .table-responsive > .table-bordered > thead > tr > td:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:first-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child { border-left: 0; } .panel > .table-bordered > thead > tr > th:last-child, .panel > .table-bordered > thead > tr > td:last-child, .panel > .table-bordered > tbody > tr > th:last-child, .panel > .table-bordered > tbody > tr > td:last-child, .panel > .table-bordered > tfoot > tr > th:last-child, .panel > .table-bordered > tfoot > tr > td:last-child, .panel > .table-responsive > .table-bordered > thead > tr > th:last-child, .panel > .table-responsive > .table-bordered > thead > tr > td:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > th:last-child, .panel > .table-responsive > .table-bordered > tbody > tr > td:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child, .panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child { border-right: 0; } .panel > .table-bordered > thead > tr:first-child > td, .panel > .table-bordered > thead > tr:first-child > th, .panel > .table-bordered > tbody > tr:first-child > td, .panel > .table-bordered > tbody > tr:first-child > th, .panel > .table-responsive > .table-bordered > thead > tr:first-child > td, .panel > .table-responsive > .table-bordered > thead > tr:first-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:first-child > th { border-bottom: 0; } .panel > .table-bordered > tbody > tr:last-child > td, .panel > .table-bordered > tbody > tr:last-child > th, .panel > .table-bordered > tfoot > tr:last-child > td, .panel > .table-bordered > tfoot > tr:last-child > th, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > td, .panel > .table-responsive > .table-bordered > tbody > tr:last-child > th, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td, .panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th { border-bottom: 0; } .panel > .table-responsive { border: 0; margin-bottom: 0; } .panel-group { margin-bottom: 27px; } .panel-group .panel { margin-bottom: 0; border-radius: 3px; } .panel-group .panel + .panel { margin-top: 5px; } .panel-group .panel-heading { border-bottom: 0; } .panel-group .panel-heading + .panel-collapse > .panel-body, .panel-group .panel-heading + .panel-collapse > .list-group { border-top: 1px solid #ddd; } .panel-group .panel-footer { border-top: 0; } .panel-group .panel-footer + .panel-collapse .panel-body { border-bottom: 1px solid #ddd; } .panel-default { border-color: #ddd; } .panel-default > .panel-heading { color: #212121; background-color: #f5f5f5; border-color: #ddd; } .panel-default > .panel-heading + .panel-collapse > .panel-body { border-top-color: #ddd; } .panel-default > .panel-heading .badge { color: #f5f5f5; background-color: #212121; } .panel-default > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #ddd; } .panel-primary { border-color: #5a9ddb; } .panel-primary > .panel-heading { color: #fff; background-color: #5a9ddb; border-color: #5a9ddb; } .panel-primary > .panel-heading + .panel-collapse > .panel-body { border-top-color: #5a9ddb; } .panel-primary > .panel-heading .badge { color: #5a9ddb; background-color: #fff; } .panel-primary > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #5a9ddb; } .panel-success { border-color: #d6e9c6; } .panel-success > .panel-heading { color: #fff; background-color: #4CAF50; border-color: #d6e9c6; } .panel-success > .panel-heading + .panel-collapse > .panel-body { border-top-color: #d6e9c6; } .panel-success > .panel-heading .badge { color: #4CAF50; background-color: #fff; } .panel-success > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #d6e9c6; } .panel-info { border-color: #cba4dd; } .panel-info > .panel-heading { color: #fff; background-color: #9C27B0; border-color: #cba4dd; } .panel-info > .panel-heading + .panel-collapse > .panel-body { border-top-color: #cba4dd; } .panel-info > .panel-heading .badge { color: #9C27B0; background-color: #fff; } .panel-info > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #cba4dd; } .panel-warning { border-color: #ffc599; } .panel-warning > .panel-heading { color: #fff; background-color: #ff9800; border-color: #ffc599; } .panel-warning > .panel-heading + .panel-collapse > .panel-body { border-top-color: #ffc599; } .panel-warning > .panel-heading .badge { color: #ff9800; background-color: #fff; } .panel-warning > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #ffc599; } .panel-danger { border-color: #f7a4af; } .panel-danger > .panel-heading { color: #fff; background-color: #e51c23; border-color: #f7a4af; } .panel-danger > .panel-heading + .panel-collapse > .panel-body { border-top-color: #f7a4af; } .panel-danger > .panel-heading .badge { color: #e51c23; background-color: #fff; } .panel-danger > .panel-footer + .panel-collapse > .panel-body { border-bottom-color: #f7a4af; } .embed-responsive { position: relative; display: block; height: 0; padding: 0; overflow: hidden; } .embed-responsive .embed-responsive-item, .embed-responsive iframe, .embed-responsive embed, .embed-responsive object, .embed-responsive video { position: absolute; top: 0; left: 0; bottom: 0; height: 100%; width: 100%; border: 0; } .embed-responsive-16by9 { padding-bottom: 56.25%; } .embed-responsive-4by3 { padding-bottom: 75%; } .well { min-height: 20px; padding: 19px; margin-bottom: 20px; background-color: #f5f5f5; border: 1px solid transparent; border-radius: 3px; -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); } .well blockquote { border-color: #ddd; border-color: rgba(0, 0, 0, 0.15); } .well-lg { padding: 24px; border-radius: 3px; } .well-sm { padding: 9px; border-radius: 3px; } .close { float: right; font-size: 22.5px; font-weight: normal; line-height: 1; color: #000; text-shadow: none; opacity: 0.2; filter: alpha(opacity=20); } .close:hover, .close:focus { color: #000; text-decoration: none; cursor: pointer; opacity: 0.5; filter: alpha(opacity=50); } button.close { padding: 0; cursor: pointer; background: transparent; border: 0; -webkit-appearance: none; } .modal-open { overflow: hidden; } .modal { display: none; overflow: hidden; position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1050; -webkit-overflow-scrolling: touch; outline: 0; } .modal.fade .modal-dialog { -webkit-transform: translate(0, -25%); -ms-transform: translate(0, -25%); -o-transform: translate(0, -25%); transform: translate(0, -25%); -webkit-transition: -webkit-transform 0.3s ease-out; -moz-transition: -moz-transform 0.3s ease-out; -o-transition: -o-transform 0.3s ease-out; transition: transform 0.3s ease-out; } .modal.in .modal-dialog { -webkit-transform: translate(0, 0); -ms-transform: translate(0, 0); -o-transform: translate(0, 0); transform: translate(0, 0); } .modal-open .modal { overflow-x: hidden; overflow-y: auto; } .modal-dialog { position: relative; width: auto; margin: 10px; } .modal-content { position: relative; background-color: #fff; border: 1px solid #999; border: 1px solid transparent; border-radius: 3px; -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5); background-clip: padding-box; outline: 0; } .modal-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1040; background-color: #000; } .modal-backdrop.fade { opacity: 0; filter: alpha(opacity=0); } .modal-backdrop.in { opacity: 0.5; filter: alpha(opacity=50); } .modal-header { padding: 15px; border-bottom: 1px solid transparent; } .modal-header:before, .modal-header:after { content: " "; display: table; } .modal-header:after { clear: both; } .modal-header .close { margin-top: -2px; } .modal-title { margin: 0; line-height: 1.846; } .modal-body { position: relative; padding: 15px; } .modal-footer { padding: 15px; text-align: right; border-top: 1px solid transparent; } .modal-footer:before, .modal-footer:after { content: " "; display: table; } .modal-footer:after { clear: both; } .modal-footer .btn + .btn { margin-left: 5px; margin-bottom: 0; } .modal-footer .btn-group .btn + .btn { margin-left: -1px; } .modal-footer .btn-block + .btn-block { margin-left: 0; } .modal-scrollbar-measure { position: absolute; top: -9999px; width: 50px; height: 50px; overflow: scroll; } @media (min-width: 768px) { .modal-dialog { width: 600px; margin: 30px auto; } .modal-content { -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5); } .modal-sm { width: 300px; } } @media (min-width: 992px) { .modal-lg { width: 900px; } } .tooltip { position: absolute; z-index: 1070; display: block; font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; font-style: normal; font-weight: normal; letter-spacing: normal; line-break: auto; line-height: 1.846; text-align: left; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; white-space: normal; word-break: normal; word-spacing: normal; word-wrap: normal; font-size: 13px; opacity: 0; filter: alpha(opacity=0); } .tooltip.in { opacity: 0.9; filter: alpha(opacity=90); } .tooltip.top { margin-top: -3px; padding: 5px 0; } .tooltip.right { margin-left: 3px; padding: 0 5px; } .tooltip.bottom { margin-top: 3px; padding: 5px 0; } .tooltip.left { margin-left: -3px; padding: 0 5px; } .tooltip-inner { max-width: 200px; padding: 3px 8px; color: #fff; text-align: center; background-color: #727272; border-radius: 3px; } .tooltip-arrow { position: absolute; width: 0; height: 0; border-color: transparent; border-style: solid; } .tooltip.top .tooltip-arrow { bottom: 0; left: 50%; margin-left: -5px; border-width: 5px 5px 0; border-top-color: #727272; } .tooltip.top-left .tooltip-arrow { bottom: 0; right: 5px; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #727272; } .tooltip.top-right .tooltip-arrow { bottom: 0; left: 5px; margin-bottom: -5px; border-width: 5px 5px 0; border-top-color: #727272; } .tooltip.right .tooltip-arrow { top: 50%; left: 0; margin-top: -5px; border-width: 5px 5px 5px 0; border-right-color: #727272; } .tooltip.left .tooltip-arrow { top: 50%; right: 0; margin-top: -5px; border-width: 5px 0 5px 5px; border-left-color: #727272; } .tooltip.bottom .tooltip-arrow { top: 0; left: 50%; margin-left: -5px; border-width: 0 5px 5px; border-bottom-color: #727272; } .tooltip.bottom-left .tooltip-arrow { top: 0; right: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #727272; } .tooltip.bottom-right .tooltip-arrow { top: 0; left: 5px; margin-top: -5px; border-width: 0 5px 5px; border-bottom-color: #727272; } .popover { position: absolute; top: 0; left: 0; z-index: 1060; display: none; max-width: 276px; padding: 1px; font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; font-style: normal; font-weight: normal; letter-spacing: normal; line-break: auto; line-height: 1.846; text-align: left; text-align: start; text-decoration: none; text-shadow: none; text-transform: none; white-space: normal; word-break: normal; word-spacing: normal; word-wrap: normal; font-size: 15px; background-color: #fff; background-clip: padding-box; border: 1px solid transparent; border: 1px solid transparent; border-radius: 3px; -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); } .popover.top { margin-top: -10px; } .popover.right { margin-left: 10px; } .popover.bottom { margin-top: 10px; } .popover.left { margin-left: -10px; } .popover-title { margin: 0; padding: 8px 14px; font-size: 15px; background-color: #f7f7f7; border-bottom: 1px solid #ebebeb; border-radius: 2px 2px 0 0; } .popover-content { padding: 9px 14px; } .popover > .arrow, .popover > .arrow:after { position: absolute; display: block; width: 0; height: 0; border-color: transparent; border-style: solid; } .popover > .arrow { border-width: 11px; } .popover > .arrow:after { border-width: 10px; content: ""; } .popover.top > .arrow { left: 50%; margin-left: -11px; border-bottom-width: 0; border-top-color: rgba(0, 0, 0, 0); border-top-color: fadein(transparent, 12%); bottom: -11px; } .popover.top > .arrow:after { content: " "; bottom: 1px; margin-left: -10px; border-bottom-width: 0; border-top-color: #fff; } .popover.right > .arrow { top: 50%; left: -11px; margin-top: -11px; border-left-width: 0; border-right-color: rgba(0, 0, 0, 0); border-right-color: fadein(transparent, 12%); } .popover.right > .arrow:after { content: " "; left: 1px; bottom: -10px; border-left-width: 0; border-right-color: #fff; } .popover.bottom > .arrow { left: 50%; margin-left: -11px; border-top-width: 0; border-bottom-color: rgba(0, 0, 0, 0); border-bottom-color: fadein(transparent, 12%); top: -11px; } .popover.bottom > .arrow:after { content: " "; top: 1px; margin-left: -10px; border-top-width: 0; border-bottom-color: #fff; } .popover.left > .arrow { top: 50%; right: -11px; margin-top: -11px; border-right-width: 0; border-left-color: rgba(0, 0, 0, 0); border-left-color: fadein(transparent, 12%); } .popover.left > .arrow:after { content: " "; right: 1px; border-right-width: 0; border-left-color: #fff; bottom: -10px; } .carousel { position: relative; } .carousel-inner { position: relative; overflow: hidden; width: 100%; } .carousel-inner > .item { display: none; position: relative; -webkit-transition: 0.6s ease-in-out left; -o-transition: 0.6s ease-in-out left; transition: 0.6s ease-in-out left; } .carousel-inner > .item > img, .carousel-inner > .item > a > img { display: block; max-width: 100%; height: auto; line-height: 1; } @media all and (transform-3d), (-webkit-transform-3d) { .carousel-inner > .item { -webkit-transition: -webkit-transform 0.6s ease-in-out; -moz-transition: -moz-transform 0.6s ease-in-out; -o-transition: -o-transform 0.6s ease-in-out; transition: transform 0.6s ease-in-out; -webkit-backface-visibility: hidden; -moz-backface-visibility: hidden; backface-visibility: hidden; -webkit-perspective: 1000px; -moz-perspective: 1000px; perspective: 1000px; } .carousel-inner > .item.next, .carousel-inner > .item.active.right { -webkit-transform: translate3d(100%, 0, 0); transform: translate3d(100%, 0, 0); left: 0; } .carousel-inner > .item.prev, .carousel-inner > .item.active.left { -webkit-transform: translate3d(-100%, 0, 0); transform: translate3d(-100%, 0, 0); left: 0; } .carousel-inner > .item.next.left, .carousel-inner > .item.prev.right, .carousel-inner > .item.active { -webkit-transform: translate3d(0, 0, 0); transform: translate3d(0, 0, 0); left: 0; } } .carousel-inner > .active, .carousel-inner > .next, .carousel-inner > .prev { display: block; } .carousel-inner > .active { left: 0; } .carousel-inner > .next, .carousel-inner > .prev { position: absolute; top: 0; width: 100%; } .carousel-inner > .next { left: 100%; } .carousel-inner > .prev { left: -100%; } .carousel-inner > .next.left, .carousel-inner > .prev.right { left: 0; } .carousel-inner > .active.left { left: -100%; } .carousel-inner > .active.right { left: 100%; } .carousel-control { position: absolute; top: 0; left: 0; bottom: 0; width: 15%; opacity: 0.5; filter: alpha(opacity=50); font-size: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); background-color: rgba(0, 0, 0, 0); } .carousel-control.left { background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.0001) 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1); } .carousel-control.right { left: auto; right: 0; background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0%, rgba(0, 0, 0, 0.5) 100%); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1); } .carousel-control:hover, .carousel-control:focus { outline: 0; color: #fff; text-decoration: none; opacity: 0.9; filter: alpha(opacity=90); } .carousel-control .icon-prev, .carousel-control .icon-next, .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right { position: absolute; top: 50%; margin-top: -10px; z-index: 5; display: inline-block; } .carousel-control .icon-prev, .carousel-control .glyphicon-chevron-left { left: 50%; margin-left: -10px; } .carousel-control .icon-next, .carousel-control .glyphicon-chevron-right { right: 50%; margin-right: -10px; } .carousel-control .icon-prev, .carousel-control .icon-next { width: 20px; height: 20px; line-height: 1; font-family: serif; } .carousel-control .icon-prev:before { content: '\2039'; } .carousel-control .icon-next:before { content: '\203a'; } .carousel-indicators { position: absolute; bottom: 10px; left: 50%; z-index: 15; width: 60%; margin-left: -30%; padding-left: 0; list-style: none; text-align: center; } .carousel-indicators li { display: inline-block; width: 10px; height: 10px; margin: 1px; text-indent: -999px; border: 1px solid #fff; border-radius: 10px; cursor: pointer; background-color: #000 \9; background-color: rgba(0, 0, 0, 0); } .carousel-indicators .active { margin: 0; width: 12px; height: 12px; background-color: #fff; } .carousel-caption { position: absolute; left: 15%; right: 15%; bottom: 20px; z-index: 10; padding-top: 20px; padding-bottom: 20px; color: #fff; text-align: center; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6); } .carousel-caption .btn { text-shadow: none; } @media screen and (min-width: 768px) { .carousel-control .glyphicon-chevron-left, .carousel-control .glyphicon-chevron-right, .carousel-control .icon-prev, .carousel-control .icon-next { width: 30px; height: 30px; margin-top: -10px; font-size: 30px; } .carousel-control .glyphicon-chevron-left, .carousel-control .icon-prev { margin-left: -10px; } .carousel-control .glyphicon-chevron-right, .carousel-control .icon-next { margin-right: -10px; } .carousel-caption { left: 20%; right: 20%; padding-bottom: 30px; } .carousel-indicators { bottom: 20px; } } .clearfix:before, .clearfix:after { content: " "; display: table; } .clearfix:after { clear: both; } .center-block { display: block; margin-left: auto; margin-right: auto; } .pull-right { float: right !important; } .pull-left { float: left !important; } .hide { display: none !important; } .show { display: block !important; } .invisible { visibility: hidden; } .text-hide { font: 0/0 a; color: transparent; text-shadow: none; background-color: transparent; border: 0; } .hidden { display: none !important; } .affix { position: fixed; } @-ms-viewport { width: device-width; } .visible-xs { display: none !important; } .visible-sm { display: none !important; } .visible-md { display: none !important; } .visible-lg { display: none !important; } .visible-xs-block, .visible-xs-inline, .visible-xs-inline-block, .visible-sm-block, .visible-sm-inline, .visible-sm-inline-block, .visible-md-block, .visible-md-inline, .visible-md-inline-block, .visible-lg-block, .visible-lg-inline, .visible-lg-inline-block { display: none !important; } @media (max-width: 767px) { .visible-xs { display: block !important; } table.visible-xs { display: table !important; } tr.visible-xs { display: table-row !important; } th.visible-xs, td.visible-xs { display: table-cell !important; } } @media (max-width: 767px) { .visible-xs-block { display: block !important; } } @media (max-width: 767px) { .visible-xs-inline { display: inline !important; } } @media (max-width: 767px) { .visible-xs-inline-block { display: inline-block !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm { display: block !important; } table.visible-sm { display: table !important; } tr.visible-sm { display: table-row !important; } th.visible-sm, td.visible-sm { display: table-cell !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-block { display: block !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-inline { display: inline !important; } } @media (min-width: 768px) and (max-width: 991px) { .visible-sm-inline-block { display: inline-block !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md { display: block !important; } table.visible-md { display: table !important; } tr.visible-md { display: table-row !important; } th.visible-md, td.visible-md { display: table-cell !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-block { display: block !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-inline { display: inline !important; } } @media (min-width: 992px) and (max-width: 1199px) { .visible-md-inline-block { display: inline-block !important; } } @media (min-width: 1200px) { .visible-lg { display: block !important; } table.visible-lg { display: table !important; } tr.visible-lg { display: table-row !important; } th.visible-lg, td.visible-lg { display: table-cell !important; } } @media (min-width: 1200px) { .visible-lg-block { display: block !important; } } @media (min-width: 1200px) { .visible-lg-inline { display: inline !important; } } @media (min-width: 1200px) { .visible-lg-inline-block { display: inline-block !important; } } @media (max-width: 767px) { .hidden-xs { display: none !important; } } @media (min-width: 768px) and (max-width: 991px) { .hidden-sm { display: none !important; } } @media (min-width: 992px) and (max-width: 1199px) { .hidden-md { display: none !important; } } @media (min-width: 1200px) { .hidden-lg { display: none !important; } } .visible-print { display: none !important; } @media print { .visible-print { display: block !important; } table.visible-print { display: table !important; } tr.visible-print { display: table-row !important; } th.visible-print, td.visible-print { display: table-cell !important; } } .visible-print-block { display: none !important; } @media print { .visible-print-block { display: block !important; } } .visible-print-inline { display: none !important; } @media print { .visible-print-inline { display: inline !important; } } .visible-print-inline-block { display: none !important; } @media print { .visible-print-inline-block { display: inline-block !important; } } @media print { .hidden-print { display: none !important; } } /*! * tidyverse theme * Copyright 2016 RStudio, Inc. */ .navbar { border: none; -webkit-box-shadow: 0 3px 15px 0px rgba(0, 0, 0, 0.1); box-shadow: 0 3px 15px 0px rgba(0, 0, 0, 0.1); min-height: 50px; padding: 5px 0; } .navbar-brand { font-family: "Source Code Pro", Menlo, Monaco, Consolas, "Courier New", monospace; font-weight: normal; font-size: 32px; padding: 0 0 0 54px; height: 50px; line-height: 50px; background-image: url(../logo.png); background-size: 32px auto; background-repeat: no-repeat; background-position: 15px center; } .navbar-nav li a { padding-top: 10px; padding-bottom: 0; line-height: inherit; } .navbar-inverse .navbar-form input[type=text], .navbar-inverse .navbar-form input[type=password] { color: #fff; -webkit-box-shadow: inset 0 -1px 0 #d8e8f6; box-shadow: inset 0 -1px 0 #d8e8f6; } .navbar-inverse .navbar-form input[type=text]::-moz-placeholder, .navbar-inverse .navbar-form input[type=password]::-moz-placeholder { color: #d8e8f6; opacity: 1; } .navbar-inverse .navbar-form input[type=text]:-ms-input-placeholder, .navbar-inverse .navbar-form input[type=password]:-ms-input-placeholder { color: #d8e8f6; } .navbar-inverse .navbar-form input[type=text]::-webkit-input-placeholder, .navbar-inverse .navbar-form input[type=password]::-webkit-input-placeholder { color: #d8e8f6; } .navbar-inverse .navbar-form input[type=text]:focus, .navbar-inverse .navbar-form input[type=password]:focus { -webkit-box-shadow: inset 0 -2px 0 #fff; box-shadow: inset 0 -2px 0 #fff; } .btn-default:focus { background-color: #fff; } .btn-default:hover, .btn-default:active:hover { background-color: #f0f0f0; } .btn-default:active { -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); } .btn-primary:focus { background-color: #5a9ddb; } .btn-primary:hover, .btn-primary:active:hover { background-color: #418ed6; } .btn-primary:active { -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); } .btn-success:focus { background-color: #4CAF50; } .btn-success:hover, .btn-success:active:hover { background-color: #439a46; } .btn-success:active { -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); } .btn-info:focus { background-color: #9C27B0; } .btn-info:hover, .btn-info:active:hover { background-color: #862197; } .btn-info:active { -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); } .btn-warning:focus { background-color: #ff9800; } .btn-warning:hover, .btn-warning:active:hover { background-color: #e08600; } .btn-warning:active { -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); } .btn-danger:focus { background-color: #e51c23; } .btn-danger:hover, .btn-danger:active:hover { background-color: #cb171e; } .btn-danger:active { -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); } .btn-link:focus { background-color: #fff; } .btn-link:hover, .btn-link:active:hover { background-color: #f0f0f0; } .btn-link:active { -webkit-box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.4); } .btn { text-transform: uppercase; border: none; -webkit-box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4); -webkit-transition: all 0.4s; -o-transition: all 0.4s; transition: all 0.4s; position: relative; } .btn:after { content: ""; display: block; position: absolute; width: 100%; height: 100%; top: 0; left: 0; background-image: -webkit-radial-gradient(circle, #000 10%, transparent 10.01%); background-image: radial-gradient(circle, #000 10%, transparent 10.01%); background-repeat: no-repeat; background-size: 1000% 1000%; background-position: 50%; opacity: 0; pointer-events: none; transition: background .5s, opacity 1s; } .btn:active:after { background-size: 0% 0%; opacity: .2; transition: 0s; } .btn-link { border-radius: 3px; -webkit-box-shadow: none; box-shadow: none; color: #444; } .btn-link:hover, .btn-link:focus { -webkit-box-shadow: none; box-shadow: none; color: #444; text-decoration: none; } .btn-default.disabled { background-color: rgba(0, 0, 0, 0.1); color: rgba(0, 0, 0, 0.4); opacity: 1; } .btn-group .btn + .btn, .btn-group .btn + .btn-group, .btn-group .btn-group + .btn, .btn-group .btn-group + .btn-group { margin-left: 0; } .btn-group-vertical > .btn + .btn, .btn-group-vertical > .btn + .btn-group, .btn-group-vertical > .btn-group + .btn, .btn-group-vertical > .btn-group + .btn-group { margin-top: 0; } body { -webkit-font-smoothing: antialiased; letter-spacing: .1px; } p { margin: 0 0 1em; } input, button { -webkit-font-smoothing: antialiased; letter-spacing: .1px; } a { -webkit-transition: all 0.25s; -o-transition: all 0.25s; transition: all 0.25s; } .table-hover > tbody > tr, .table-hover > tbody > tr > th, .table-hover > tbody > tr > td { -webkit-transition: all 0.2s; -o-transition: all 0.2s; transition: all 0.2s; } label { font-weight: normal; } textarea, textarea.form-control, input.form-control, input[type=text], input[type=password], input[type=email], input[type=number], [type=text].form-control, [type=password].form-control, [type=email].form-control, [type=tel].form-control, [contenteditable].form-control { padding: 0; border: none; border-radius: 0; -webkit-appearance: none; -webkit-box-shadow: inset 0 -1px 0 #ddd; box-shadow: inset 0 -1px 0 #ddd; font-size: 16px; } textarea:focus, textarea.form-control:focus, input.form-control:focus, input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, input[type=number]:focus, [type=text].form-control:focus, [type=password].form-control:focus, [type=email].form-control:focus, [type=tel].form-control:focus, [contenteditable].form-control:focus { -webkit-box-shadow: inset 0 -2px 0 #5a9ddb; box-shadow: inset 0 -2px 0 #5a9ddb; } textarea[disabled], textarea[readonly], textarea.form-control[disabled], textarea.form-control[readonly], input.form-control[disabled], input.form-control[readonly], input[type=text][disabled], input[type=text][readonly], input[type=password][disabled], input[type=password][readonly], input[type=email][disabled], input[type=email][readonly], input[type=number][disabled], input[type=number][readonly], [type=text].form-control[disabled], [type=text].form-control[readonly], [type=password].form-control[disabled], [type=password].form-control[readonly], [type=email].form-control[disabled], [type=email].form-control[readonly], [type=tel].form-control[disabled], [type=tel].form-control[readonly], [contenteditable].form-control[disabled], [contenteditable].form-control[readonly] { -webkit-box-shadow: none; box-shadow: none; border-bottom: 1px dotted #ddd; } textarea.input-sm, .input-group-sm > textarea.form-control, .input-group-sm > textarea.input-group-addon, .input-group-sm > .input-group-btn > textarea.btn, textarea.form-control.input-sm, .input-group-sm > textarea.form-control, .input-group-sm > .input-group-btn > textarea.form-control.btn, input.form-control.input-sm, .input-group-sm > input.form-control, .input-group-sm > .input-group-btn > input.form-control.btn, input[type=text].input-sm, .input-group-sm > input[type=text].form-control, .input-group-sm > input[type=text].input-group-addon, .input-group-sm > .input-group-btn > input[type=text].btn, input[type=password].input-sm, .input-group-sm > input[type=password].form-control, .input-group-sm > input[type=password].input-group-addon, .input-group-sm > .input-group-btn > input[type=password].btn, input[type=email].input-sm, .input-group-sm > input[type=email].form-control, .input-group-sm > input[type=email].input-group-addon, .input-group-sm > .input-group-btn > input[type=email].btn, input[type=number].input-sm, .input-group-sm > input[type=number].form-control, .input-group-sm > input[type=number].input-group-addon, .input-group-sm > .input-group-btn > input[type=number].btn, [type=text].form-control.input-sm, .input-group-sm > [type=text].form-control, .input-group-sm > .input-group-btn > [type=text].form-control.btn, [type=password].form-control.input-sm, .input-group-sm > [type=password].form-control, .input-group-sm > .input-group-btn > [type=password].form-control.btn, [type=email].form-control.input-sm, .input-group-sm > [type=email].form-control, .input-group-sm > .input-group-btn > [type=email].form-control.btn, [type=tel].form-control.input-sm, .input-group-sm > [type=tel].form-control, .input-group-sm > .input-group-btn > [type=tel].form-control.btn, [contenteditable].form-control.input-sm, .input-group-sm > [contenteditable].form-control, .input-group-sm > .input-group-btn > [contenteditable].form-control.btn { font-size: 13px; } textarea.input-lg, .input-group-lg > textarea.form-control, .input-group-lg > textarea.input-group-addon, .input-group-lg > .input-group-btn > textarea.btn, textarea.form-control.input-lg, .input-group-lg > textarea.form-control, .input-group-lg > .input-group-btn > textarea.form-control.btn, input.form-control.input-lg, .input-group-lg > input.form-control, .input-group-lg > .input-group-btn > input.form-control.btn, input[type=text].input-lg, .input-group-lg > input[type=text].form-control, .input-group-lg > input[type=text].input-group-addon, .input-group-lg > .input-group-btn > input[type=text].btn, input[type=password].input-lg, .input-group-lg > input[type=password].form-control, .input-group-lg > input[type=password].input-group-addon, .input-group-lg > .input-group-btn > input[type=password].btn, input[type=email].input-lg, .input-group-lg > input[type=email].form-control, .input-group-lg > input[type=email].input-group-addon, .input-group-lg > .input-group-btn > input[type=email].btn, input[type=number].input-lg, .input-group-lg > input[type=number].form-control, .input-group-lg > input[type=number].input-group-addon, .input-group-lg > .input-group-btn > input[type=number].btn, [type=text].form-control.input-lg, .input-group-lg > [type=text].form-control, .input-group-lg > .input-group-btn > [type=text].form-control.btn, [type=password].form-control.input-lg, .input-group-lg > [type=password].form-control, .input-group-lg > .input-group-btn > [type=password].form-control.btn, [type=email].form-control.input-lg, .input-group-lg > [type=email].form-control, .input-group-lg > .input-group-btn > [type=email].form-control.btn, [type=tel].form-control.input-lg, .input-group-lg > [type=tel].form-control, .input-group-lg > .input-group-btn > [type=tel].form-control.btn, [contenteditable].form-control.input-lg, .input-group-lg > [contenteditable].form-control, .input-group-lg > .input-group-btn > [contenteditable].form-control.btn { font-size: 19px; } select, select.form-control { border: 0; border-radius: 0; -webkit-appearance: none; -moz-appearance: none; appearance: none; padding-left: 0; padding-right: 0\9; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEVmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmaP/QSjAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=); background-size: 13px; background-repeat: no-repeat; background-position: right center; -webkit-box-shadow: inset 0 -1px 0 #ddd; box-shadow: inset 0 -1px 0 #ddd; font-size: 16px; line-height: 1.5; } select::-ms-expand, select.form-control::-ms-expand { display: none; } select.input-sm, .input-group-sm > select.form-control, .input-group-sm > select.input-group-addon, .input-group-sm > .input-group-btn > select.btn, select.form-control.input-sm, .input-group-sm > select.form-control, .input-group-sm > .input-group-btn > select.form-control.btn { font-size: 13px; } select.input-lg, .input-group-lg > select.form-control, .input-group-lg > select.input-group-addon, .input-group-lg > .input-group-btn > select.btn, select.form-control.input-lg, .input-group-lg > select.form-control, .input-group-lg > .input-group-btn > select.form-control.btn { font-size: 19px; } select:focus, select.form-control:focus { -webkit-box-shadow: inset 0 -2px 0 #5a9ddb; box-shadow: inset 0 -2px 0 #5a9ddb; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAMAAACelLz8AAAAJ1BMVEUhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISEhISF8S9ewAAAADHRSTlMAAgMJC0uWpKa6wMxMdjkoAAAANUlEQVR4AeXJyQEAERAAsNl7Hf3X6xt0QL6JpZWq30pdvdadme+0PMdzvHm8YThHcT1H7K0BtOMDniZhWOgAAAAASUVORK5CYII=); } select[multiple], select.form-control[multiple] { background: none; } .radio label, .radio-inline label, .checkbox label, .checkbox-inline label { padding-left: 25px; } .radio input[type="radio"], .radio input[type="checkbox"], .radio-inline input[type="radio"], .radio-inline input[type="checkbox"], .checkbox input[type="radio"], .checkbox input[type="checkbox"], .checkbox-inline input[type="radio"], .checkbox-inline input[type="checkbox"] { margin-left: -25px; } input[type="radio"], .radio input[type="radio"], .radio-inline input[type="radio"] { position: relative; margin-top: 6px; margin-right: 4px; vertical-align: top; border: none; background-color: transparent; -webkit-appearance: none; appearance: none; cursor: pointer; } input[type="radio"]:focus, .radio input[type="radio"]:focus, .radio-inline input[type="radio"]:focus { outline: none; } input[type="radio"]:before, input[type="radio"]:after, .radio input[type="radio"]:before, .radio input[type="radio"]:after, .radio-inline input[type="radio"]:before, .radio-inline input[type="radio"]:after { content: ""; display: block; width: 18px; height: 18px; border-radius: 50%; -webkit-transition: 240ms; -o-transition: 240ms; transition: 240ms; } input[type="radio"]:before, .radio input[type="radio"]:before, .radio-inline input[type="radio"]:before { position: absolute; left: 0; top: -3px; background-color: #5a9ddb; -webkit-transform: scale(0); -ms-transform: scale(0); -o-transform: scale(0); transform: scale(0); } input[type="radio"]:after, .radio input[type="radio"]:after, .radio-inline input[type="radio"]:after { position: relative; top: -3px; border: 2px solid #666; } input[type="radio"]:checked:before, .radio input[type="radio"]:checked:before, .radio-inline input[type="radio"]:checked:before { -webkit-transform: scale(0.5); -ms-transform: scale(0.5); -o-transform: scale(0.5); transform: scale(0.5); } input[type="radio"]:disabled:checked:before, .radio input[type="radio"]:disabled:checked:before, .radio-inline input[type="radio"]:disabled:checked:before { background-color: #bbb; } input[type="radio"]:checked:after, .radio input[type="radio"]:checked:after, .radio-inline input[type="radio"]:checked:after { border-color: #5a9ddb; } input[type="radio"]:disabled:after, input[type="radio"]:disabled:checked:after, .radio input[type="radio"]:disabled:after, .radio input[type="radio"]:disabled:checked:after, .radio-inline input[type="radio"]:disabled:after, .radio-inline input[type="radio"]:disabled:checked:after { border-color: #bbb; } input[type="checkbox"], .checkbox input[type="checkbox"], .checkbox-inline input[type="checkbox"] { position: relative; border: none; margin-bottom: -4px; -webkit-appearance: none; appearance: none; cursor: pointer; } input[type="checkbox"]:focus, .checkbox input[type="checkbox"]:focus, .checkbox-inline input[type="checkbox"]:focus { outline: none; } input[type="checkbox"]:focus:after, .checkbox input[type="checkbox"]:focus:after, .checkbox-inline input[type="checkbox"]:focus:after { border-color: #5a9ddb; } input[type="checkbox"]:after, .checkbox input[type="checkbox"]:after, .checkbox-inline input[type="checkbox"]:after { content: ""; display: block; width: 18px; height: 18px; margin-top: -2px; margin-right: 5px; border: 2px solid #666; border-radius: 2px; -webkit-transition: 240ms; -o-transition: 240ms; transition: 240ms; } input[type="checkbox"]:checked:before, .checkbox input[type="checkbox"]:checked:before, .checkbox-inline input[type="checkbox"]:checked:before { content: ""; position: absolute; top: 0; left: 6px; display: table; width: 6px; height: 12px; border: 2px solid #fff; border-top-width: 0; border-left-width: 0; -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); -o-transform: rotate(45deg); transform: rotate(45deg); } input[type="checkbox"]:checked:after, .checkbox input[type="checkbox"]:checked:after, .checkbox-inline input[type="checkbox"]:checked:after { background-color: #5a9ddb; border-color: #5a9ddb; } input[type="checkbox"]:disabled:after, .checkbox input[type="checkbox"]:disabled:after, .checkbox-inline input[type="checkbox"]:disabled:after { border-color: #bbb; } input[type="checkbox"]:disabled:checked:after, .checkbox input[type="checkbox"]:disabled:checked:after, .checkbox-inline input[type="checkbox"]:disabled:checked:after { background-color: #bbb; border-color: transparent; } .has-warning input:not([type=checkbox]), .has-warning .form-control, .has-warning input.form-control[readonly], .has-warning input[type=text][readonly], .has-warning [type=text].form-control[readonly], .has-warning input:not([type=checkbox]):focus, .has-warning .form-control:focus { border-bottom: none; -webkit-box-shadow: inset 0 -2px 0 #ff9800; box-shadow: inset 0 -2px 0 #ff9800; } .has-error input:not([type=checkbox]), .has-error .form-control, .has-error input.form-control[readonly], .has-error input[type=text][readonly], .has-error [type=text].form-control[readonly], .has-error input:not([type=checkbox]):focus, .has-error .form-control:focus { border-bottom: none; -webkit-box-shadow: inset 0 -2px 0 #e51c23; box-shadow: inset 0 -2px 0 #e51c23; } .has-success input:not([type=checkbox]), .has-success .form-control, .has-success input.form-control[readonly], .has-success input[type=text][readonly], .has-success [type=text].form-control[readonly], .has-success input:not([type=checkbox]):focus, .has-success .form-control:focus { border-bottom: none; -webkit-box-shadow: inset 0 -2px 0 #4CAF50; box-shadow: inset 0 -2px 0 #4CAF50; } .has-warning .input-group-addon, .has-error .input-group-addon, .has-success .input-group-addon { color: #666; border-color: transparent; background-color: transparent; } .form-group-lg select, .form-group-lg select.form-control { line-height: 1.5; } .nav-tabs > li > a, .nav-tabs > li > a:focus { margin-right: 0; background-color: transparent; border: none; color: #444; -webkit-box-shadow: inset 0 -1px 0 #ddd; box-shadow: inset 0 -1px 0 #ddd; -webkit-transition: all 0.2s; -o-transition: all 0.2s; transition: all 0.2s; } .nav-tabs > li > a:hover, .nav-tabs > li > a:focus:hover { background-color: transparent; -webkit-box-shadow: inset 0 -2px 0 #5a9ddb; box-shadow: inset 0 -2px 0 #5a9ddb; color: #5a9ddb; } .nav-tabs > li.active > a, .nav-tabs > li.active > a:focus { border: none; -webkit-box-shadow: inset 0 -2px 0 #5a9ddb; box-shadow: inset 0 -2px 0 #5a9ddb; color: #5a9ddb; } .nav-tabs > li.active > a:hover, .nav-tabs > li.active > a:focus:hover { border: none; color: #5a9ddb; } .nav-tabs > li.disabled > a { -webkit-box-shadow: inset 0 -1px 0 #ddd; box-shadow: inset 0 -1px 0 #ddd; } .nav-tabs.nav-justified > li > a, .nav-tabs.nav-justified > li > a:hover, .nav-tabs.nav-justified > li > a:focus, .nav-tabs.nav-justified > .active > a, .nav-tabs.nav-justified > .active > a:hover, .nav-tabs.nav-justified > .active > a:focus { border: none; } .nav-tabs .dropdown-menu { margin-top: 0; } .dropdown-menu { margin-top: 0; border: none; -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } .alert { border: none; color: #fff; } .alert-success { background-color: #4CAF50; } .alert-info { background-color: #9C27B0; } .alert-warning { background-color: #ff9800; } .alert-danger { background-color: #e51c23; } .alert a:not(.close):not(.btn), .alert .alert-link { color: #fff; font-weight: bold; } .alert .close { color: #fff; } .badge { padding: 4px 6px 4px; } .progress { position: relative; z-index: 1; height: 6px; border-radius: 0; -webkit-box-shadow: none; box-shadow: none; } .progress-bar { -webkit-box-shadow: none; box-shadow: none; } .progress-bar:last-child { border-radius: 0 3px 3px 0; } .progress-bar:last-child:before { display: block; content: ""; position: absolute; width: 100%; height: 100%; left: 0; right: 0; z-index: -1; background-color: #edf4fb; } .progress-bar-success:last-child.progress-bar:before { background-color: #c7e7c8; } .progress-bar-info:last-child.progress-bar:before { background-color: #edc9f3; } .progress-bar-warning:last-child.progress-bar:before { background-color: #ffe0b3; } .progress-bar-danger:last-child.progress-bar:before { background-color: #f28e92; } .close { font-size: 34px; font-weight: 300; line-height: 24px; opacity: 0.6; -webkit-transition: all 0.2s; -o-transition: all 0.2s; transition: all 0.2s; } .close:hover { opacity: 1; } .list-group-item { padding: 15px; } .list-group-item-text { color: #bbb; } .well { border-radius: 0; -webkit-box-shadow: none; box-shadow: none; } .panel { border: none; border-radius: 2px; -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } .panel-heading { border-bottom: none; } .panel-footer { border-top: none; } .popover { border: none; -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3); } .carousel-caption h1, .carousel-caption h2, .carousel-caption h3, .carousel-caption h4, .carousel-caption h5, .carousel-caption h6 { color: inherit; } /*# sourceMappingURL=tidyverse.css.map */ lubridate/inst/doc/0000755000176200001440000000000013263152652013754 5ustar liggesuserslubridate/inst/doc/lubridate.Rmd0000644000176200001440000002051013201152061016353 0ustar liggesusers--- title: "Do more with dates and times in R" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Do more with dates and times in R} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(comment = "#>", collapse = TRUE) ``` (This vignette is an updated version of the blog post first published at [r-statistics](http://www.r-statistics.com/2012/03/do-more-with-dates-and-times-in-r-with-lubridate-1-1-0/)_ Lubridate is an R package that makes it easier to work with dates and times. Below is a concise tour of some of the things lubridate can do for you. Lubridate was created by Garrett Grolemund and Hadley Wickham, and is now maintained by Vitalie Spinu. ## Parsing dates and times Getting R to agree that your data contains the dates and times you think it does can be tricky. Lubridate simplifies that. Identify the order in which the year, month, and day appears in your dates. Now arrange "y", "m", and "d" in the same order. This is the name of the function in lubridate that will parse your dates. For example, ```{r} library(lubridate) ymd("20110604") mdy("06-04-2011") dmy("04/06/2011") ``` Lubridate's parse functions handle a wide variety of formats and separators, which simplifies the parsing process. If your date includes time information, add h, m, and/or s to the name of the function. `ymd_hms` is probably the most common date time format. To read the dates in with a certain time zone, supply the official name of that time zone in the `tz` argument. ```{r} arrive <- ymd_hms("2011-06-04 12:00:00", tz = "Pacific/Auckland") arrive leave <- ymd_hms("2011-08-10 14:00:00", tz = "Pacific/Auckland") leave ``` ## Setting and Extracting information Extract information from date times with the functions `second`, `minute`, `hour`, `day`, `wday`, `yday`, `week`, `month`, `year`, and `tz`. You can also use each of these to set (i.e, change) the given information. Notice that this will alter the date time. `wday` and `month` have an optional `label` argument, which replaces their numeric output with the name of the weekday or month. ```{r} second(arrive) second(arrive) <- 25 arrive second(arrive) <- 0 wday(arrive) wday(arrive, label = TRUE) ``` ## Time Zones There are two very useful things to do with dates and time zones. First, display the same moment in a different time zone. Second, create a new moment by combining an existing clock time with a new time zone. These are accomplished by `with_tz` and `force_tz`. For example, a while ago I was in Auckland, New Zealand. I arranged to meet the co-author of lubridate, Hadley, over skype at 9:00 in the morning Auckland time. What time was that for Hadley who was back in Houston, TX? ```{r} meeting <- ymd_hms("2011-07-01 09:00:00", tz = "Pacific/Auckland") with_tz(meeting, "America/Chicago") ``` So the meetings occurred at 4:00 Hadley's time (and the day before no less). Of course, this was the same actual moment of time as 9:00 in New Zealand. It just appears to be a different day due to the curvature of the Earth. What if Hadley made a mistake and signed on at 9:00 his time? What time would it then be my time? ```{r} mistake <- force_tz(meeting, "America/Chicago") with_tz(mistake, "Pacific/Auckland") ``` His call would arrive at 2:00 am my time! Luckily he never did that. ## Time Intervals You can save an interval of time as an Interval class object with lubridate. This is quite useful! For example, my stay in Auckland lasted from June 4, 2011 to August 10, 2011 (which we've already saved as arrive and leave). We can create this interval in one of two ways: ```{r} auckland <- interval(arrive, leave) auckland auckland <- arrive %--% leave auckland ``` My mentor at the University of Auckland, Chris, traveled to various conferences that year including the Joint Statistical Meetings (JSM). This took him out of the country from July 20 until the end of August. ```{r} jsm <- interval(ymd(20110720, tz = "Pacific/Auckland"), ymd(20110831, tz = "Pacific/Auckland")) jsm ``` Will my visit overlap with and his travels? Yes. ```{r} int_overlaps(jsm, auckland) ``` Then I better make hay while the sun shines! For what part of my visit will Chris be there? ```{r} setdiff(auckland, jsm) ``` Other functions that work with intervals include `int_start`, `int_end`, `int_flip`, `int_shift`, `int_aligns`, `union`, `intersect`, `setdiff`, and `%within%`. ## Arithmetic with date times Intervals are specific time spans (because they are tied to specific dates), but lubridate also supplies two general time span classes: Durations and Periods. Helper functions for creating periods are named after the units of time (plural). Helper functions for creating durations follow the same format but begin with a "d" (for duration) or, if you prefer, and "e" (for exact). ```{r} minutes(2) ## period dminutes(2) ## duration ``` Why two classes? Because the timeline is not as reliable as the number line. The Duration class will always supply mathematically precise results. A duration year will always equal 365 days. Periods, on the other hand, fluctuate the same way the timeline does to give intuitive results. This makes them useful for modeling clock times. For example, durations will be honest in the face of a leap year, but periods may return what you want: ```{r} leap_year(2011) ## regular year ymd(20110101) + dyears(1) ymd(20110101) + years(1) leap_year(2012) ## leap year ymd(20120101) + dyears(1) ymd(20120101) + years(1) ``` You can use periods and durations to do basic arithmetic with date times. For example, if I wanted to set up a reoccuring weekly skype meeting with Hadley, it would occur on: ```{r} meetings <- meeting + weeks(0:5) ``` Hadley travelled to conferences at the same time as Chris. Which of these meetings would be affected? The last two. ```{r} meetings %within% jsm ``` How long was my stay in Auckland? ```{r} auckland / ddays(1) auckland / ddays(2) auckland / dminutes(1) ``` And so on. Alternatively, we can do modulo and integer division. Sometimes this is more sensible than division - it is not obvious how to express a remainder as a fraction of a month because the length of a month constantly changes. ```{r} auckland %/% months(1) auckland %% months(1) ``` Modulo with an timespan returns the remainder as a new (smaller) interval. You can turn this or any interval into a generalized time span with `as.period`. ```{r} as.period(auckland %% months(1)) as.period(auckland) ``` ### If anyone drove a time machine, they would crash The length of months and years change so often that doing arithmetic with them can be unintuitive. Consider a simple operation, `January 31st + one month`. Should the answer be 1. `February 31st` (which doesn't exist) 2. `March 4th` (31 days after January 31), or 3. `February 28th` (assuming its not a leap year) A basic property of arithmetic is that `a + b - b = a`. Only solution 1 obeys this property, but it is an invalid date. I've tried to make lubridate as consistent as possible by invoking the following rule *if adding or subtracting a month or a year creates an invalid date, lubridate will return an NA*. This is new with version 1.3.0, so if you're an old hand with lubridate be sure to remember this! If you thought solution 2 or 3 was more useful, no problem. You can still get those results with clever arithmetic, or by using the special `%m+%` and `%m-%` operators. `%m+%` and `%m-%` automatically roll dates back to the last day of the month, should that be necessary. ```{r} jan31 <- ymd("2013-01-31") jan31 + months(0:11) floor_date(jan31, "month") + months(0:11) + days(31) jan31 %m+% months(0:11) ``` Notice that this will only affect arithmetic with months (and arithmetic with years if your start date it Feb 29). ## Vectorization The code in lubridate is vectorized and ready to be used in both interactive settings and within functions. As an example, I offer a function for advancing a date to the last day of the month ```{r} last_day <- function(date) { ceiling_date(date, "month") - days(1) } ``` ## Further Resources To learn more about lubridate, including the specifics of periods and durations, please read the [original lubridate paper](http://www.jstatsoft.org/v40/i03/). Questions about lubridate can be addressed to the lubridate google group. Bugs and feature requests should be submitted to the [lubridate development page](http://github.com/hadley/lubridate) on github. lubridate/inst/doc/lubridate.R0000644000176200001440000000550213263152651016053 0ustar liggesusers## ---- include = FALSE---------------------------------------------------- knitr::opts_chunk$set(comment = "#>", collapse = TRUE) ## ------------------------------------------------------------------------ library(lubridate) ymd("20110604") mdy("06-04-2011") dmy("04/06/2011") ## ------------------------------------------------------------------------ arrive <- ymd_hms("2011-06-04 12:00:00", tz = "Pacific/Auckland") arrive leave <- ymd_hms("2011-08-10 14:00:00", tz = "Pacific/Auckland") leave ## ------------------------------------------------------------------------ second(arrive) second(arrive) <- 25 arrive second(arrive) <- 0 wday(arrive) wday(arrive, label = TRUE) ## ------------------------------------------------------------------------ meeting <- ymd_hms("2011-07-01 09:00:00", tz = "Pacific/Auckland") with_tz(meeting, "America/Chicago") ## ------------------------------------------------------------------------ mistake <- force_tz(meeting, "America/Chicago") with_tz(mistake, "Pacific/Auckland") ## ------------------------------------------------------------------------ auckland <- interval(arrive, leave) auckland auckland <- arrive %--% leave auckland ## ------------------------------------------------------------------------ jsm <- interval(ymd(20110720, tz = "Pacific/Auckland"), ymd(20110831, tz = "Pacific/Auckland")) jsm ## ------------------------------------------------------------------------ int_overlaps(jsm, auckland) ## ------------------------------------------------------------------------ setdiff(auckland, jsm) ## ------------------------------------------------------------------------ minutes(2) ## period dminutes(2) ## duration ## ------------------------------------------------------------------------ leap_year(2011) ## regular year ymd(20110101) + dyears(1) ymd(20110101) + years(1) leap_year(2012) ## leap year ymd(20120101) + dyears(1) ymd(20120101) + years(1) ## ------------------------------------------------------------------------ meetings <- meeting + weeks(0:5) ## ------------------------------------------------------------------------ meetings %within% jsm ## ------------------------------------------------------------------------ auckland / ddays(1) auckland / ddays(2) auckland / dminutes(1) ## ------------------------------------------------------------------------ auckland %/% months(1) auckland %% months(1) ## ------------------------------------------------------------------------ as.period(auckland %% months(1)) as.period(auckland) ## ------------------------------------------------------------------------ jan31 <- ymd("2013-01-31") jan31 + months(0:11) floor_date(jan31, "month") + months(0:11) + days(31) jan31 %m+% months(0:11) ## ------------------------------------------------------------------------ last_day <- function(date) { ceiling_date(date, "month") - days(1) } lubridate/inst/doc/lubridate.html0000644000176200001440000006311513263152652016623 0ustar liggesusers Do more with dates and times in R

Do more with dates and times in R

(This vignette is an updated version of the blog post first published at r-statistics_

Lubridate is an R package that makes it easier to work with dates and times. Below is a concise tour of some of the things lubridate can do for you. Lubridate was created by Garrett Grolemund and Hadley Wickham, and is now maintained by Vitalie Spinu.

Parsing dates and times

Getting R to agree that your data contains the dates and times you think it does can be tricky. Lubridate simplifies that. Identify the order in which the year, month, and day appears in your dates. Now arrange “y”, “m”, and “d” in the same order. This is the name of the function in lubridate that will parse your dates. For example,

library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following object is masked from 'package:base':
#> 
#>     date
ymd("20110604")
#> [1] "2011-06-04"
mdy("06-04-2011")
#> [1] "2011-06-04"
dmy("04/06/2011")
#> [1] "2011-06-04"

Lubridate’s parse functions handle a wide variety of formats and separators, which simplifies the parsing process.

If your date includes time information, add h, m, and/or s to the name of the function. ymd_hms is probably the most common date time format. To read the dates in with a certain time zone, supply the official name of that time zone in the tz argument.

arrive <- ymd_hms("2011-06-04 12:00:00", tz = "Pacific/Auckland")
arrive
#> [1] "2011-06-04 12:00:00 NZST"
leave <- ymd_hms("2011-08-10 14:00:00", tz = "Pacific/Auckland")
leave
#> [1] "2011-08-10 14:00:00 NZST"

Setting and Extracting information

Extract information from date times with the functions second, minute, hour, day, wday, yday, week, month, year, and tz. You can also use each of these to set (i.e, change) the given information. Notice that this will alter the date time. wday and month have an optional label argument, which replaces their numeric output with the name of the weekday or month.

second(arrive)
#> [1] 0
second(arrive) <- 25
arrive
#> [1] "2011-06-04 12:00:25 NZST"
second(arrive) <- 0

wday(arrive)
#> [1] 7
wday(arrive, label = TRUE)
#> [1] Sat
#> Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat

Time Zones

There are two very useful things to do with dates and time zones. First, display the same moment in a different time zone. Second, create a new moment by combining an existing clock time with a new time zone. These are accomplished by with_tz and force_tz.

For example, a while ago I was in Auckland, New Zealand. I arranged to meet the co-author of lubridate, Hadley, over skype at 9:00 in the morning Auckland time. What time was that for Hadley who was back in Houston, TX?

meeting <- ymd_hms("2011-07-01 09:00:00", tz = "Pacific/Auckland")
with_tz(meeting, "America/Chicago")
#> [1] "2011-06-30 16:00:00 CDT"

So the meetings occurred at 4:00 Hadley’s time (and the day before no less). Of course, this was the same actual moment of time as 9:00 in New Zealand. It just appears to be a different day due to the curvature of the Earth.

What if Hadley made a mistake and signed on at 9:00 his time? What time would it then be my time?

mistake <- force_tz(meeting, "America/Chicago")
with_tz(mistake, "Pacific/Auckland")
#> [1] "2011-07-02 02:00:00 NZST"

His call would arrive at 2:00 am my time! Luckily he never did that.

Time Intervals

You can save an interval of time as an Interval class object with lubridate. This is quite useful! For example, my stay in Auckland lasted from June 4, 2011 to August 10, 2011 (which we’ve already saved as arrive and leave). We can create this interval in one of two ways:

auckland <- interval(arrive, leave) 
auckland
#> [1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST
auckland <- arrive %--% leave
auckland
#> [1] 2011-06-04 12:00:00 NZST--2011-08-10 14:00:00 NZST

My mentor at the University of Auckland, Chris, traveled to various conferences that year including the Joint Statistical Meetings (JSM). This took him out of the country from July 20 until the end of August.

jsm <- interval(ymd(20110720, tz = "Pacific/Auckland"), ymd(20110831, tz = "Pacific/Auckland"))
jsm
#> [1] 2011-07-20 NZST--2011-08-31 NZST

Will my visit overlap with and his travels? Yes.

int_overlaps(jsm, auckland)
#> [1] TRUE

Then I better make hay while the sun shines! For what part of my visit will Chris be there?

setdiff(auckland, jsm)
#> [1] 2011-06-04 12:00:00 NZST--2011-07-20 NZST

Other functions that work with intervals include int_start, int_end, int_flip, int_shift, int_aligns, union, intersect, setdiff, and %within%.

Arithmetic with date times

Intervals are specific time spans (because they are tied to specific dates), but lubridate also supplies two general time span classes: Durations and Periods. Helper functions for creating periods are named after the units of time (plural). Helper functions for creating durations follow the same format but begin with a “d” (for duration) or, if you prefer, and “e” (for exact).

minutes(2) ## period
#> [1] "2M 0S"
dminutes(2) ## duration
#> [1] "120s (~2 minutes)"

Why two classes? Because the timeline is not as reliable as the number line. The Duration class will always supply mathematically precise results. A duration year will always equal 365 days. Periods, on the other hand, fluctuate the same way the timeline does to give intuitive results. This makes them useful for modeling clock times. For example, durations will be honest in the face of a leap year, but periods may return what you want:

leap_year(2011) ## regular year
#> [1] FALSE
ymd(20110101) + dyears(1)
#> [1] "2012-01-01"
ymd(20110101) + years(1)
#> [1] "2012-01-01"

leap_year(2012) ## leap year
#> [1] TRUE
ymd(20120101) + dyears(1)
#> [1] "2012-12-31"
ymd(20120101) + years(1)
#> [1] "2013-01-01"

You can use periods and durations to do basic arithmetic with date times. For example, if I wanted to set up a reoccuring weekly skype meeting with Hadley, it would occur on:

meetings <- meeting + weeks(0:5)

Hadley travelled to conferences at the same time as Chris. Which of these meetings would be affected? The last two.

meetings %within% jsm
#> [1] FALSE FALSE FALSE  TRUE  TRUE  TRUE

How long was my stay in Auckland?

auckland / ddays(1)
#> [1] 67.08333
auckland / ddays(2)
#> [1] 33.54167
auckland / dminutes(1)
#> [1] 96600

And so on. Alternatively, we can do modulo and integer division. Sometimes this is more sensible than division - it is not obvious how to express a remainder as a fraction of a month because the length of a month constantly changes.

auckland %/% months(1)
#> Note: method with signature 'Timespan#Timespan' chosen for function '%/%',
#>  target signature 'Interval#Period'.
#>  "Interval#ANY", "ANY#Period" would also be valid
#> [1] 2
auckland %% months(1)
#> [1] 2011-08-04 12:00:00 NZST--2011-08-10 14:00:00 NZST

Modulo with an timespan returns the remainder as a new (smaller) interval. You can turn this or any interval into a generalized time span with as.period.

as.period(auckland %% months(1))
#> [1] "6d 2H 0M 0S"
as.period(auckland)
#> [1] "2m 6d 2H 0M 0S"

If anyone drove a time machine, they would crash

The length of months and years change so often that doing arithmetic with them can be unintuitive. Consider a simple operation, January 31st + one month. Should the answer be

  1. February 31st (which doesn’t exist)
  2. March 4th (31 days after January 31), or
  3. February 28th (assuming its not a leap year)

A basic property of arithmetic is that a + b - b = a. Only solution 1 obeys this property, but it is an invalid date. I’ve tried to make lubridate as consistent as possible by invoking the following rule if adding or subtracting a month or a year creates an invalid date, lubridate will return an NA. This is new with version 1.3.0, so if you’re an old hand with lubridate be sure to remember this!

If you thought solution 2 or 3 was more useful, no problem. You can still get those results with clever arithmetic, or by using the special %m+% and %m-% operators. %m+% and %m-% automatically roll dates back to the last day of the month, should that be necessary.

jan31 <- ymd("2013-01-31")
jan31 + months(0:11)
#>  [1] "2013-01-31" NA           "2013-03-31" NA           "2013-05-31"
#>  [6] NA           "2013-07-31" "2013-08-31" NA           "2013-10-31"
#> [11] NA           "2013-12-31"
floor_date(jan31, "month") + months(0:11) + days(31)
#>  [1] "2013-02-01" "2013-03-04" "2013-04-01" "2013-05-02" "2013-06-01"
#>  [6] "2013-07-02" "2013-08-01" "2013-09-01" "2013-10-02" "2013-11-01"
#> [11] "2013-12-02" "2014-01-01"
jan31 %m+% months(0:11)
#>  [1] "2013-01-31" "2013-02-28" "2013-03-31" "2013-04-30" "2013-05-31"
#>  [6] "2013-06-30" "2013-07-31" "2013-08-31" "2013-09-30" "2013-10-31"
#> [11] "2013-11-30" "2013-12-31"

Notice that this will only affect arithmetic with months (and arithmetic with years if your start date it Feb 29).

Vectorization

The code in lubridate is vectorized and ready to be used in both interactive settings and within functions. As an example, I offer a function for advancing a date to the last day of the month

last_day <- function(date) {
  ceiling_date(date, "month") - days(1)
}

Further Resources

To learn more about lubridate, including the specifics of periods and durations, please read the original lubridate paper. Questions about lubridate can be addressed to the lubridate google group. Bugs and feature requests should be submitted to the lubridate development page on github.

lubridate/tests/0000755000176200001440000000000013102102352013354 5ustar liggesuserslubridate/tests/testthat.R0000644000176200001440000000014213102102352015334 0ustar liggesusersif (packageVersion("testthat") >= "0.7.1.99") { library(testthat) test_check("lubridate") } lubridate/tests/testthat/0000755000176200001440000000000013263357253015240 5ustar liggesuserslubridate/tests/testthat/test-ops-integer-division.R0000644000176200001440000000465613201152061022407 0ustar liggesuserscontext("Integer division operations") test_that("integer division works for interval numerator", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") expect_error(int1 %/% int2) expect_equal(int1 %/% months(1), 12) expect_error(months(12) %/% int1) expect_equal(int1 %/% ddays(1), 365) expect_error(ddays(365) %/% int1) }) test_that("integer division works for interval numerator with vectors", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") int3 <- ymd("2009-01-01") %--% ymd("2010-01-01") expect_error(int2 %/% c(int1, int3)) expect_error(c(int1, int2) %/% int3) expect_equal(int1 %/% months(1:2), c(12, 6)) expect_error(months(c(6, 12)) %/% int1) expect_equal(int1 %/% ddays(1:2), c(365, 182)) expect_equal(c(int1, int2) %/% ddays(2), c(182, 365)) }) test_that("integer division works for period numerator", { int1 <- ymd("2010-01-01") %--% ymd("2010-12-31") expect_error(years(2) %/% int1) expect_equal(years(1) %/% days(1), 365) expect_equal(months(13) %/% years(1), 1) expect_error(months(1) %/% ddays(1)) }) test_that("integer division works for period numerator with vectors", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") expect_error(years(2) %/% c(int1, int2)) expect_error(years(1:2) %/% int1) expect_equal(years(1) %/% months(1:2), c(12, 6)) expect_equal(months(c(6, 12)) %/% years(1), c(0, 1)) expect_error(years(1) %/% ddays(1:2)) expect_error(years(1:2) %/% ddays(2)) }) test_that("integer division works for duration numerator", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") expect_error(dyears(2) %/% int1) expect_error(dyears(1) %/% months(1)) expect_equal(dyears(1) %/% ddays(1), 365) }) test_that("integer division works for duration numerator with vectors", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") expect_error(dyears(2) %/% c(int1, int2)) expect_error(dyears(1:2) %/% int1) expect_error(dyears(1) %/% months(1:2)) expect_error(dyears(1:2) %/% years(1)) expect_equal(dyears(1) %/% ddays(1:2), c(365, 182)) expect_equal(dyears(1:2) %/% ddays(2), c(182, 365)) }) test_that("integer division works with Period denominator (#235)", { a <- interval(ymd(20140331), ymd(20140519)) expect_equal(a %/% months(1), 1) a <- interval(ymd(20140331), ymd(20140419)) expect_equal(a %/% months(1), 0) }) lubridate/tests/testthat/test-utilities.R0000644000176200001440000000200713201152061020330 0ustar liggesuserscontext("Utilities") test_that("leap_year correctly identifies leap years", { x <- as.POSIXct("2009-08-03 12:01:59", tz = "UTC") y <- as.POSIXct("2008-08-03 12:01:59", tz = "UTC") expect_that(leap_year(x), is_false()) expect_that(leap_year(y), is_true()) }) test_that("leap_year handles vectors", { x <- as.POSIXct(c("2008-08-03 12:01:59", "2009-08-03 12:01:59"), tz = "UTC") expect_that(leap_year(x)[1], is_true()) expect_that(leap_year(x)[2], is_false()) expect_that(leap_year(as.Date(x))[1], is_true()) expect_that(leap_year(as.Date(x))[2], is_false()) }) test_that("leap_year handles various classes of date-time object", { x <- as.POSIXct(c("2008-08-03 12:01:59", "2009-08-03 12:01:59"), tz = "UTC") expect_that(leap_year(x)[1], is_true()) expect_that(leap_year(x)[2], is_false()) expect_that(leap_year(as.Date(x))[1], is_true()) expect_that(leap_year(as.Date(x))[2], is_false()) expect_that(leap_year(as.POSIXlt(x))[1], is_true()) expect_that(leap_year(as.POSIXlt(x))[2], is_false()) }) lubridate/tests/testthat/test-ops-addition.R0000644000176200001440000002552113234067471020735 0ustar liggesuserscontext("Addition operations") test_that("addition handles daylight savings time", { x <- as.POSIXct("2010-03-14 00:00:00", tz = "America/New_York") y <- as.POSIXct("2010-03-15 01:00:00", tz = "America/New_York") expect_that(x + days(1), equals(as.POSIXct( "2010-03-15 00:00:00", tz = "America/New_York"))) expect_that(x + ddays(1), equals(y)) }) test_that("subtraction handles daylight savings time", { x <- as.POSIXct("2010-03-15 00:00:00", tz = "America/New_York") y <- as.POSIXct("2010-03-13 23:00:00", tz = "America/New_York") expect_that(x - days(1), equals(as.POSIXct( "2010-03-14 00:00:00", tz = "America/New_York"))) expect_that(x - ddays(1), equals(y)) }) test_that("addition works as expected for instants", { x <- as.POSIXct("2008-01-01 00:00:00", tz = "UTC") y <- as.POSIXlt("2008-01-01 00:00:00", tz = "UTC") z <- as.Date("2008-01-01") expect_equal(x + years(1), as.POSIXct("2009-01-01 00:00:00", tz = "UTC")) expect_equal(y + years(1), as.POSIXlt("2009-01-01 00:00:00", tz = "UTC")) expect_equal(z + years(1), as.Date("2009-01-01")) expect_that(x + dyears(1), equals(as.POSIXct("2008-12-31 00:00:00", tz = "UTC"))) expect_that(y + dyears(1), equals(as.POSIXlt("2008-12-31 00:00:00", tz = "UTC"))) expect_that(z + dyears(1), equals(as.Date("2008-12-31"))) time1 <- as.POSIXct("2008-08-02 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") int <- interval(time1, time2) num <- as.numeric(time2) - as.numeric(time1) expect_error(x + int) expect_error(y + int) expect_error(z + int) }) test_that("addition with instants returns correct class", { x <- as.POSIXct("2008-01-02 00:00:00", tz = "UTC") y <- as.POSIXlt("2008-01-02 00:00:00", tz = "UTC") z <- as.Date("2008-01-01") expect_is(x + years(1), "POSIXct") expect_is(y + years(1), "POSIXlt") expect_is(z + years(1), "Date") expect_that(x + dyears(1), is_a("POSIXct")) expect_that(y + dyears(1), is_a("POSIXlt")) expect_that(z + dyears(1), is_a("Date")) }) test_that("addition works as expected for periods", { time1 <- as.POSIXct("2008-01-02 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-08-03 00:00:00", tz = "UTC") int <- interval(time1, time2) expect_that(years(1) + 1, equals(period(seconds = 1, years = 1))) expect_that(years(1) + as.POSIXct("2008-01-01 00:00:00", tz = "UTC"), equals(as.POSIXct("2009-01-01 00:00:00", tz = "UTC"))) expect_that(years(1) + as.POSIXlt("2008-01-01 00:00:00", tz = "UTC"), equals(as.POSIXlt("2009-01-01 00:00:00", tz = "UTC"))) expect_that(years(1) + minutes(3), equals(period(minutes = 3, years = 1))) expect_error(years(1) + dyears(1)) expect_error(years(1) + int) }) test_that("addition with periods returns correct class", { expect_is(years(1) + 1, "Period") expect_is(years(1) + as.POSIXct( "2008-01-01 00:00:00", tz = "UTC"), "POSIXt") expect_is(years(1) + as.POSIXlt( "2008-01-01 00:00:00", tz = "UTC"), "POSIXlt") expect_is(years(1) + minutes(3), "Period") }) test_that("addition works as expected for durations", { x <- as.POSIXct("2008-01-01 00:00:00", tz = "UTC") y <- as.POSIXct("2008-12-31 00:00:00", tz = "UTC") time1 <- as.POSIXct("2008-01-02 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-08-03 00:00:00", tz = "UTC") int <- interval(time1, time2) expect_equal(dyears(1) + 1, duration(31536001)) expect_equal(dyears(1) + x, y) expect_equal(dyears(1) + dyears(1), dyears(2)) expect_error(dyears(1) + minutes(3)) expect_error(dyears(1) + int) }) test_that("addition with durations returns correct class", { ct <- as.POSIXct("2008-01-01 00:00:00", tz = "UTC") lt <- as.POSIXlt("2008-01-01 00:00:00", tz = "UTC") expect_that(dyears(1) + 1, is_a("Duration")) expect_that(dyears(1) + ct, is_a("POSIXct")) expect_that(dyears(1) + lt, is_a("POSIXlt")) expect_that(dyears(1) + dyears(1), is_a("Duration")) }) test_that("addition works as expected for intervals", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") time3 <- as.POSIXct("2008-01-01 00:00:00", tz = "UTC") diff <- difftime(time2, time1) int <- interval(time1, time2) expect_error(int + time3) expect_error(int + time1) expect_error(int + 1) expect_error(int + minutes(3)) expect_error(int + dyears(1)) time5 <- as.POSIXct("2010-08-03 00:00:00", tz = "UTC") int3 <- interval(time2, time5) expect_error(int + int3) }) #### Vectors test_that("adding vectors works as expected for instants", { x <- as.POSIXct(c("2008-01-01 00:00:00", "2009-01-01 00:00:00"), tz = "UTC") y <- as.POSIXlt(c("2008-01-01 00:00:00", "2009-01-01 00:00:00"), tz = "UTC") z <- c(as.Date("2008-01-01"), as.Date("2008-01-10")) expect_that(x + years(1), equals(as.POSIXct(c( "2009-01-01 00:00:00", "2010-01-01 00:00:00"), tz = "UTC"))) expect_that(y + years(1), equals(as.POSIXlt(c( "2009-01-01 00:00:00", "2010-01-01 00:00:00"), tz = "UTC"))) expect_that(z + years(1), equals(as.Date(c("2009-01-01", "2009-01-10")))) expect_that(x + dyears(1), equals(as.POSIXct(c( "2008-12-31 00:00:00", "2010-01-01 00:00:00"), tz = "UTC"))) expect_that(y + dyears(1), equals(as.POSIXlt(c( "2008-12-31 00:00:00", "2010-01-01 00:00:00"), tz = "UTC"))) expect_that(z + dyears(1), equals(as.Date(c("2008-12-31", "2009-01-09")))) time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") int <- interval(time1, time2) num <- as.numeric(time2) - as.numeric(time1) expect_error(x + int) expect_error(y + int) expect_error(z + int) }) test_that("adding vectors works as expected for periods", { expect_that(years(1:2) + 1, equals(period(seconds = 1, years = c(1, 2)))) expect_that(years(1:2) + as.POSIXct("2008-01-01 00:00:00", tz = "UTC"), equals(as.POSIXct(c("2009-01-01 00:00:00", "2010-01-01 00:00:00"), tz = "UTC"))) expect_that(years(1:2) + as.POSIXlt("2008-01-01 00:00:00", tz = "UTC"), equals(as.POSIXlt(c("2009-01-01 00:00:00", "2010-01-01 00:00:00"), tz = "UTC"))) expect_that(years(1:2) + minutes(3), equals(period( minutes = 3, years = c(1, 2)))) expect_error(years(1:2) + dyears(1)) time1 <- as.POSIXct("2008-01-02 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-08-03 00:00:00", tz = "UTC") int <- interval(time1, time2) expect_error(years(1:2) + int) }) test_that("adding vectors works as expected for durations", { w <- as.POSIXct("2007-01-01 00:00:00", tz = "UTC") x <- as.POSIXct("2008-01-01 00:00:00", tz = "UTC") y <- as.POSIXct(c("2008-01-01 00:00:00", "2008-12-31 00:00:00"), tz = "UTC") dur <- dminutes(1:2) + 1 expect_equal(dur@.Data, c(61, 121)) expect_equal(dyears(1:2) + w, y) expect_that(dyears(1:2) + as.POSIXlt(w), equals(as.POSIXlt(y))) expect_error(dyears(1:2) + minutes(3)) expect_that(dyears(1:2) + dyears(1), equals(dyears(2:3))) time1 <- as.POSIXct("2008-01-02 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-08-03 00:00:00", tz = "UTC") int <- interval(time1, time2) expect_error(dyears(1:2) + int) }) test_that("adding vectors works as expected for intervals", { time1 <- as.POSIXct("2008-08-03 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-08-03 00:00:00", tz = "UTC") time3 <- as.POSIXct("2010-08-03 00:00:00", tz = "UTC") int <- interval(c(time1, time2), time3) int2 <- interval(time1, time2) expect_error(int + time4) expect_error(int + 1) expect_error(int + minutes(3)) expect_error(int + dyears(1)) expect_error(int + int2) }) test_that("%m+% correctly adds months without rollover", { jan <- ymd_hms("2010-01-31 03:04:05") ends <- ymd_hms(c("2010-02-28 03:04:05", "2010-03-31 03:04:05", "2010-04-30 03:04:05")) expect_equal(jan %m+% months(1:3), ends) }) test_that("%m+% correctly adds years without rollover", { leap <- ymd("2012-02-29") next1 <- ymd("2013-02-28") next2 <- ymd("2013-03-29") expect_equal(leap %m+% years(1), next1) expect_equal(leap %m+% period(years = 1, months = 1), next2) }) test_that("%m+% correctly adds years, months, days and HMS (#286)", { date <- ymd("2012-02-29") per_all <- period(years = 1, months = 1, days = 2, hours = 1, minutes = 20, seconds = 30) per_major <- period(years = 1, months = 1) per_minor <- period(days = 2, hours = 1, minutes = 20, seconds = 30) expect_equal(date %m+% per_all, date %m+% per_major + per_minor) date <- ymd("2012-03-31") per_all <- period(months = 3, days = 30, hours = 1, minutes = 20, seconds = 30) per_major <- period(months = 3) per_minor <- period(days = 30, hours = 1, minutes = 20, seconds = 30) expect_equal(date %m+% per_all, date %m+% per_major + per_minor) }) test_that("%m+% correctly adds negative months without rollover", { may <- ymd_hms("2010-05-31 03:04:05") ends <- ymd_hms(c("2010-04-30 03:04:05", "2010-03-31 03:04:05", "2010-02-28 03:04:05")) expect_equal(may %m+% -months(1:3), ends) }) test_that("%m+% correctly adds negative years without rollover", { leap <- ymd("2012-02-29") next1 <- ymd("2011-02-28") next2 <- ymd("2011-01-29") next3 <- ymd("2011-03-29") expect_equal(leap %m+% years(-1), next1) expect_equal(leap %m+% period(years = -1, months = -1), next2) expect_equal(leap %m+% period(years = -1, months = 1), next3) }) test_that("addition with period months and years returns NA when appropriate", { jan <- ymd("2013-01-31", tz = "America/Chicago") feb <- ymd("2013-02-28", tz = "America/Chicago") mar <- ymd("2013-03-28", tz = "America/Chicago") leap <- ymd("2012-02-29", tz = "America/Chicago") mos <- ymd(c("2013-01-31", NA, "2013-03-31", NA, "2013-05-31", NA, "2013-07-31", "2013-08-31", NA, "2013-10-31", NA, "2013-12-31"), tz = "America/Chicago") yrs <- ymd(c("2012-02-29", NA, NA, NA, "2016-02-29"), tz = "America/Chicago") mos2 <- ymd(c("2013-01-31", "2012-12-31", NA, "2012-10-31", NA, "2012-08-31", "2012-07-31", NA, "2012-05-31", NA, "2012-03-31", NA), tz = "America/Chicago") yrs2 <- ymd(c("2012-02-29", NA, NA, NA, "2008-02-29"), tz = "America/Chicago") expect_equal(jan + months(0:11), mos) expect_equal(feb + months(1), mar) expect_equal(leap + years(0:4), yrs) expect_equal(jan - months(0:11), mos2) expect_equal(mar - months(1), feb) expect_equal(leap - years(0:4), yrs2) }) test_that("addition with durations containing NA", { dt <- ymd(20161018) dt_1 <- ymd(20161019) dd_1na <- ddays(c(1, NA)) dd_na1 <- ddays(c(NA, 1)) dd_nana <- ddays(c(NA, NA)) ans_1na <- add_duration_to_date(dd_1na, dt) ans_na1 <- add_duration_to_date(dd_na1, dt) ans_nana <- add_duration_to_date(dd_nana, dt) expect_is(ans_1na, "Date") expect_is(ans_na1, "Date") expect_is(ans_nana, "Date") expect_equal(ans_1na, c(dt_1, NA)) expect_equal(ans_na1, rev(c(dt_1, NA))) expect_equal(ans_nana, as.Date(c(NA, NA))) }) lubridate/tests/testthat/test-ops-subtraction.R0000644000176200001440000001055013201152061021453 0ustar liggesuserscontext("Subtraction operations") ###### subtraction for everything test_that("subtraction works as expected for instants", { x <- as.POSIXct("2008-01-01 00:00:02", tz = "UTC") y <- as.POSIXlt("2008-01-01 00:00:02", tz = "UTC") z <- as.Date("2008-01-03") expect_equal(x - years(1), as.POSIXct("2007-01-01 00:00:02", tz = "UTC")) expect_equal(y - years(1), as.POSIXlt("2007-01-01 00:00:02", tz = "UTC")) expect_equal(z - years(1), as.Date("2007-01-03")) expect_equal(x - dyears(1), as.POSIXct("2007-01-01 00:00:02", tz = "UTC")) expect_equal(y - dyears(1), as.POSIXlt("2007-01-01 00:00:02", tz = "UTC")) expect_equal(z - dyears(1), as.Date("2007-01-03")) time1 <- as.POSIXct("2007-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2008-01-01 00:00:59", tz = "UTC") int <- interval(time1, time2) num <- as.numeric(time2) - as.numeric(time1) expect_error(x - int) expect_error(y - int) expect_error(z - int) }) test_that("subtraction with instants returns correct class", { x <- as.POSIXct("2008-01-01 12:00:00", tz = "UTC") y <- as.POSIXlt("2008-01-01 12:00:00", tz = "UTC") z <- as.Date("2008-01-01") expect_that(x - years(1), is_a("POSIXct")) expect_that(y - years(1), is_a("POSIXlt")) expect_that(z - years(1), is_a("Date")) expect_that(x - dyears(1), is_a("POSIXct")) expect_that(y - dyears(1), is_a("POSIXlt")) expect_that(z - dyears(1), is_a("Date")) }) test_that("subtraction works as expected for periods", { time1 <- as.POSIXct("2008-01-02 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-02-02 00:00:00", tz = "UTC") int <- interval(time1, time2) expect_equal(years(1) - 1, period(seconds = -1, years = 1)) expect_error(years(1) - as.POSIXct("2008-01-01 00:00:00", tz = "UTC")) expect_error(years(1) - as.POSIXct("2008-01-01 00:00:00", tz = "UTC")) expect_equal(years(1) - minutes(3), period(minutes = -3, years = 1)) expect_error(years(1) - dyears(1)) expect_error(years(1) - int) }) test_that("subtraction with periods returns correct class", { expect_that(years(1) - 1, is_a("Period")) expect_that(years(1) - minutes(3), is_a("Period")) }) test_that("subtraction works as expected for durations", { time1 <- as.POSIXct("2008-01-02 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-08-03 00:00:00", tz = "UTC") int <- interval(time1, time2) expect_equal(dyears(1) - 1, duration(31535999)) expect_error(dyears(1) - as.POSIXct("2008-01-01 00:00:00", tz = "UTC")) expect_error(dyears(1) - minutes(3)) expect_equal(dyears(2) - dyears(1), dyears(1)) expect_error(dyears(1) - int) }) test_that("subtraction with durations returns correct class", { expect_that(dyears(1) - 1, is_a("Duration")) expect_that(dyears(1) - dyears(1), is_a("Duration")) }) test_that("subtraction works as expected for intervals", { time1 <- as.POSIXct("2008-08-03 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-08-03 00:00:00", tz = "UTC") time3 <- as.POSIXct("2008-11-02 00:00:00", tz = "UTC") int <- interval(time1, time2) int2 <- interval(time3, time2) expect_error(time2 - int) expect_error(int - 1) expect_error(int - time1) expect_error(int - minutes(3)) expect_error(int - dminutes(3)) expect_error(int - int2) }) test_that("%m-% correctly subtracts months without rollover", { may <- ymd_hms("2010-05-31 03:04:05") ends <- ymd_hms(c("2010-04-30 03:04:05", "2010-03-31 03:04:05", "2010-02-28 03:04:05")) expect_equal(may %m-% months(1:3), ends) }) test_that("%m-% correctly subtracts years without rollover", { leap <- ymd("2012-02-29") next1 <- ymd("2011-02-28") next2 <- ymd("2011-01-29") next3 <- ymd("2011-03-29") expect_equal(leap %m-% years(1), next1) expect_equal(leap %m-% period(years = 1, months = 1), next2) expect_equal(leap %m-% period(years = 1, months = -1), next3) }) test_that("%m-% correctly subtract negative months without rollover", { jan <- ymd_hms("2010-01-31 03:04:05") ends <- ymd_hms(c("2010-02-28 03:04:05", "2010-03-31 03:04:05", "2010-04-30 03:04:05")) expect_equal(jan %m-% -months(1:3), ends) }) test_that("%m-% correctly subtracts negative years without rollover", { leap <- ymd("2012-02-29") next1 <- ymd("2013-02-28") next2 <- ymd("2013-03-29") next3 <- ymd("2013-01-29") expect_equal(leap %m-% years(-1), next1) expect_equal(leap %m-% period(years = -1, months = -1), next2) expect_equal(leap %m-% period(years = -1, months = 1), next3) }) lubridate/tests/testthat/test-daylight-savings.R0000644000176200001440000002026713201152061021602 0ustar liggesuserscontext("Daylight savings times") test_that("force_tz returns NA for a time that falls in the spring gap", { x <- structure(1268532305, class = c("POSIXct", "POSIXt"), tzone = "UTC") y <- structure(1268618705, class = c("POSIXct", "POSIXt"), tzone = "UTC") z <- structure(1268633105, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") expect_true(is.na(force_tz(x, "America/New_York"))) expect_equal(force_tz(c(y, x), "America/New_York"), c(z, NA)) }) test_that("force_tz behaves consistently for the fall overlap", { y <- structure(1289111405, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) y2 <- structure(1289115005, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") y3 <- structure(1289104205, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") z <- structure(1289197805, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") z2 <- structure(1289201405, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") z3 <- structure(1289194205, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") cdst <- structure(1352012400, tzone = "America/Chicago", class = c("POSIXct", "POSIXt")) edst <- structure(1352008800, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) expect_equal(y + hours(1), y2) expect_equal(c(y, z) + hours(1), c(y2, z2)) expect_equal(y - hours(1), y3) expect_equal(c(y, z) - hours(1), c(y3, z3)) expect_equal(force_tz(cdst, "America/New_York"), edst) }) test_that("addition handles daylight savings time for spring gap", { x <- structure(1268542800, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") px <- structure(1268625600, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") px2 <- structure(1268712000, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") ex <- structure(1268629200, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") ex2 <- structure(1268715600, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) expect_equal(x + days(1), px) expect_equal(c(x, px) + days(1), c(px, px2)) expect_equal(x + ddays(1), ex) expect_equal(c(x, ex) + ddays(1), c(ex, ex2)) }) test_that("subtraction handles daylight savings time for spring gap", { x <- structure(1268625600, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") px <- structure(1268542800, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") px2 <- structure(1268456400, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") ex <- structure(1268539200, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") ex2 <- structure(1268452800, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) expect_equal(x - days(1), px) expect_equal(c(x, px) - days(1), c(px, px2)) expect_equal(x - ddays(1), ex) expect_equal(c(x, ex) - ddays(1), c(ex, ex2)) }) test_that("addition handles daylight savings time for fall overlap", { x <- structure(1289102400, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") px <- structure(1289192400, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") px2 <- structure(1289278800, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") ex <- structure(1289188800, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") ex2 <- structure(1289275200, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") expect_equal(x + days(1), px) expect_equal(c(x, px) + days(1), c(px, px2)) expect_equal(x + ddays(1), ex) expect_equal(c(x, ex) + ddays(1), c(ex, ex2)) }) test_that("subtraction handles daylight savings time for fall overlap", { x <- structure(1289192400, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") px <- structure(1289102400, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") px2 <- structure(1289016000, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") ex <- structure(1289106000, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) ex2 <- structure(1289019600, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) expect_equal(x - days(1), px) expect_equal(c(x, px) - days(1), c(px, px2)) expect_equal(x - ddays(1), ex) expect_equal(c(x, ex) - ddays(1), c(ex, ex2)) }) test_that("update returns NA for date-times in the spring dst gap", { poslt <- structure(list(sec = 59, min = 59L, hour = 1L, mday = 14L, mon = 2L, year = 110L, wday = 0L, yday = 72L, isdst = 0L), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"), tzone = c("America/New_York", "EST", "EDT")) x <- structure(list(sec = 59, min = 59L, hour = 1L, mday = 15L, mon = 2L, year = 110L, wday = 1L, yday = 73L, isdst = 1L), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"), tzone = c("America/New_York", "EST", "EDT")) x2 <- structure(list(sec = 59, min = 59L, hour = 2L, mday = 15L, mon = 2L, year = 110L, wday = 1L, yday = 73L, isdst = 1L), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"), tzone = c("America/New_York", "EST", "EDT")) xu <- structure(list(sec = 59, min = 59L, hour = 2L, mday = 15L, mon = 2L, year = 110L, wday = 1L, yday = 73L, isdst = 1L), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"), tzone = "UTC") expect_true(is.na(update(poslt, seconds = 61))) expect_true(is.na(update(poslt, minutes = 61))) expect_true(is.na(update(poslt, hours = 2))) expect_equal(update(c(x, poslt), hours = 2), c(x2, NA)) poslt <- structure(list(sec = 59, min = 59L, hour = 2L, mday = 13L, mon = 2L, year = 110L, wday = 6L, yday = 71L, isdst = 0L), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"), tzone = c("America/New_York", "EST", "EDT")) expect_true(is.na(update(poslt, mday = 14))) expect_true(is.na(update(poslt, wday = 8))) expect_true(is.na(update(poslt, yday = 73))) poslt <- structure(list(sec = 59, min = 59L, hour = 2L, mday = 14L, mon = 1L, year = 110L, wday = 0L, yday = 44L, isdst = 0L), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"), tzone = c("America/New_York", "EST", "EDT")) expect_true(is.na(update(poslt, months = 3))) ## poslt <- structure(list(sec = 59, min = 59L, hour = 2L, mday = 14L, mon = 2L, ## year = 109L, wday = 6L, yday = 72L, isdst = 0L), ## .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), ## class = c("POSIXlt", "POSIXt"), tzone = c("America/New_York", "EST", "EDT")) ## expect_true(is.na(update(poslt, years = 2010))) poslt <- structure(list(sec = 59, min = 59L, hour = 2L, mday = 14L, mon = 2L, year = 110L, wday = 0L, yday = 72L, isdst = 0L), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"), tzone = "UTC") expect_true(is.na(update(poslt, tz = "America/New_York"))) expect_equal(update(c(xu, poslt), tz = "America/New_York"), c(x2, NA)) }) test_that("update rollovers perform correctly across the fall overlap", { timest <- structure(1289113199, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) posct <- structure(1289109659, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) timest2 <- structure(1289116919, class = c("POSIXct", "POSIXt"), tzone = "America/New_York") timest3 <- structure(1289124119, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) timest0 <- structure(1289116859, tzone = "America/New_York", class = c("POSIXct", "POSIXt")) expect_equal(update(timest, minutes = 121), timest2) expect_equal(update(c(timest, timest2), minutes = 121), c(timest2, timest3)) expect_equal(update(timest, minutes = 0), posct) expect_equal(update(c(timest, timest2), minutes = 0), c(posct, timest0)) }) test_that("arithmetic handles fall gap in timespan appropriate way", { cdst <- structure(1352012400, tzone = "America/Chicago", class = c("POSIXct", "POSIXt")) expect_equal(cdst - seconds(1), cdst - 3601) expect_equal(cdst - dseconds(1), cdst - 1) }) lubridate/tests/testthat/test-instants.R0000644000176200001440000000536113236356705020211 0ustar liggesuserscontext("Instants") test_that("is.instant/is.timepoint works as expected", { expect_that(is.instant(234), is_false()) expect_that(is.instant(as.POSIXct("2008-08-03 13:01:59", tz = "UTC")), is_true()) expect_that(is.instant(as.POSIXlt("2008-08-03 13:01:59", tz = "UTC")), is_true()) expect_that(is.instant(Sys.Date()), is_true()) expect_that(is.instant(minutes(1)), is_false()) expect_that(is.timespan(interval( as.POSIXct("2008-08-03 13:01:59", tz = "UTC"), as.POSIXct("2009-08-03 13:01:59", tz = "UTC"))), is_true()) }) test_that("is.instant/is.timepoint handle vectors", { expect_that(is.instant(minutes(1:2)), is_false()) expect_that(is.instant(as.POSIXct(c("2008-08-03 13:01:59", "2008-08-03 13:01:59"), tz = "UTC")), is_true()) }) test_that("now() handles time zone input correctly", { expect_identical(floor_date(now("UTC"), "minute"), floor_date(as.POSIXct(format( as.POSIXct(Sys.time()), tz = "UTC"), tz = "UTC"), "minute")) }) ## test_that("today() works correctly", { ## ## Sys.Date is not correct ## ## expect_identical(today(), Sys.Date()) ## }) test_that("make_datetime returns same values as ISOdatetime", { set.seed(1000) N <- 1e4 y <- as.integer(runif(N, 1800, 2200)) m <- as.integer(runif(N, 1, 12)) d <- as.integer(runif(N, 1, 28)) H <- as.integer(runif(N, 0, 23)) M <- as.integer(runif(N, 0, 59)) S <- runif(N, 0, 59) out1 <- ISOdatetime(y, m, d, H, M, S, tz = "UTC") out2 <- make_datetime(y, m, d, H, M, S) expect_equal(out1, out2) S <- as.integer(runif(N, 0, 59)) out1 <- ISOdatetime(y, m, d, H, M, S, tz = "UTC") out2 <- make_datetime(y, m, d, H, M, S) expect_equal(out1, out2) out3 <- make_date(y, m, d) expect_equal(as.Date(out1), out3) }) test_that("make_datetime replicates as expected", { expect_equal(make_datetime(year = 1999, month = c(11, 12), day = 22, sec = c(10, 11)), as.POSIXct(c("1999-11-22 00:00:10 UTC", "1999-12-22 00:00:11 UTC"), tz = "UTC")) expect_equal(make_datetime(year = c(1999, 2000, 3000), month = c(11, 12), day = 22, sec = c(10, 11, 13, 13)), ymd_hms(c("1999-11-22 00:00:10", "2000-12-22 00:00:11", "3000-11-22 00:00:13", "1999-12-22 00:00:13"), tz = "UTC")) expect_equal(make_datetime(year = c(1999, 2000, 3000), month = c(11, 12), day = 22, sec = c(10, 11, 13, 13), tz = "America/New_York"), ymd_hms(c("1999-11-22 00:00:10", "2000-12-22 00:00:11", "3000-11-22 00:00:13", "1999-12-22 00:00:13"), tz = "America/New_York")) }) test_that("make_datetime propagates NAs as expected", { expect_equal(make_datetime(year = 1999, month = c(11, NA), day = 22, sec = c(10, 11, NA)), as.POSIXct(c("1999-11-22 00:00:10 UTC", NA, NA), tz = "UTC")) }) lubridate/tests/testthat/test-Dates.R0000644000176200001440000000411613201152061017360 0ustar liggesuserscontext("Dates") test_that("is.Date works as expected", { expect_that(is.Date(234), is_false()) expect_that(is.Date(as.POSIXct("2008-08-03 13:01:59", tz = "UTC")), is_false()) expect_that(is.Date(as.POSIXlt("2008-08-03 13:01:59", tz = "UTC")), is_false()) expect_that(is.Date(Sys.Date()), is_true()) expect_that(is.Date(minutes(1)), is_false()) expect_that(is.Date(dminutes(1)), is_false()) expect_that(is.Date(interval( as.POSIXct("2008-08-03 13:01:59", tz = "UTC"), as.POSIXct("2009-08-03 13:01:59", tz = "UTC"))), is_false()) }) test_that("is.Date handles vectors", { expect_that(is.Date(c(Sys.Date(), as.Date("2009-10-31"))), is_true()) }) test_that("as_date works", { dt1 <- as.POSIXct("2010-08-03 00:59:59.23") dt2 <- as.POSIXct("2010-08-03 00:59:59.23", tz = "Europe/London") dt3 <- as.POSIXct("2010-11-03 00:59:59.23") dt4 <- as.POSIXct("2010-11-03 00:59:59.23", tz = "Europe/London") expect_equal(as_date(dt1), as_date("2010-08-03")) expect_equal(as_date(dt2), as_date("2010-08-03")) expect_equal(as_date(dt3), as_date("2010-11-03")) expect_equal(as_date(dt4), as_date("2010-11-03")) expect_equal(as_date(dt1), as.Date("2010-08-03")) expect_equal(as_date(dt2), as.Date("2010-08-03")) expect_equal(as_date(dt3), as.Date("2010-11-03")) expect_equal(as_date(dt4), as.Date("2010-11-03")) expect_equal(as_date(10), ymd("1970-01-11")) expect_equal(as_date("2010-08-03 00:59:59.23"), as_date("2010-08-03")) expect_equal(as_date("2010-11-03 00:59:59.23"), as_date("2010-11-03")) ## tz is ignored expect_equal(as_date("2010-08-03 00:59:59.23", tz = "Europe/Amsterdam"), as_date("2010-08-03")) expect_equal(as_date("2010-11-03 00:59:59.23", tz = "Europe/Amsterdam"), as_date("2010-11-03")) ## Zulu time is part of the instant spec, so we compute on the instant object ## and not on the textual representation. expect_equal(as_date("2010-08-03 00:59:59.23Z-02"), as_date("2010-08-03")) expect_equal(as_date("2010-08-03 00:59:59.23Z+02"), as_date("2010-08-02")) expect_equal(as_date("2010-08-03 00:59:59.23Z+08"), as_date("2010-08-02")) }) lubridate/tests/testthat/test-ops-division.R0000644000176200001440000001430113201152061020740 0ustar liggesuserscontext("Division operators") test_that("division operations work for interval numerator", { int <- ymd("2009-02-03") %--% ymd("2010-01-01") smaller_int <- ymd("2009-12-01") %--% ymd("2010-01-01") bigger_int <- ymd("2009-01-01") %--% ymd("2010-02-01") smaller_dur <- ddays(20) + dhours(4) bigger_dur <- dyears(1) + dseconds(2) smaller_diff <- make_difftime(days = 100) bigger_diff <- make_difftime(days = 400) expect_error(int/smaller_int) expect_error(int/bigger_int) expect_equal(int_start(int) + days(int/days(1)), int_end(int)) expect_equal(int_start(int) + ddays(int/ddays(1)), int_end(int)) expect_equal(int/smaller_diff, 28684800/8640000) expect_equal(int/bigger_diff, 28684800/34560000) }) test_that("division works for interval numerator with vectors", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") int3 <- ymd("2009-01-01") %--% ymd("2010-01-01") smaller_diff <- make_difftime(days = 365) expect_error(c(int1, int2) / int1) expect_error(int1/c(int1, int2)) expect_equal(c(int1, int2) / years(1), c(1, 2)) expect_equal(c(int1, int2) / dyears(1), c(1, 2)) expect_equal(int1/years(1:2), c(1, 0.5)) expect_equal(int1/dyears(1:2), c(1, 0.5)) expect_equal(c(int1, int2) / smaller_diff, c(1, 2)) expect_equal(int2/c(1, 2), c(int2, int3)) expect_equal(c(int2, int2) / 2, c(int3, int3)) }) test_that("arguments are recycled in interval division", { expect_equal(interval(c('2015-03-01', '2015-03-02', '2015-03-03'), '2016-10-01') / months(1), c(19.00000000, 18.96666667, 18.93333333)) expect_equal(interval(c('2015-03-01', '2015-03-02', '2015-03-03', '2015-03-04'), '2016-10-01') / months(1:2), interval(c('2015-03-01', '2015-03-02', '2015-03-03', '2015-03-04'), '2016-10-01') / months(c(1:2, 1:2))) expect_equal(interval('2015-03-02', '2016-10-01') / months(1:3), interval(c('2015-03-02', '2015-03-02', '2015-03-02'), '2016-10-01') / months(1:3)) }) test_that("NA and Interval(0) propagate in interval division", { int0 <- interval(character(0), now()) expect_equal(int0/days(3), numeric(0)) intNA <- interval(NA, now()) expect_equal(intNA/days(3), NA_real_) }) test_that("division works for interval numerator with period denominator", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") int3 <- ymd("2009-01-01") %--% ymd("2010-01-01") expect_equal(c(int1, int2) / days(1), time_length(c(int1, int2), "days")) expect_equal(c(int1, int2) / minutes(1), time_length(c(int1, int2), "mins")) expect_equal(c(int1, int2) / months(1), c(12, 24)) expect_equal(c(int1, int2) / months(6), c(2, 4)) expect_equal(c(int1, int2) / years(1), c(1, 2)) expect_equal(c(int1, int2) / years(2), c(.5, 1)) }) test_that("dividision works for interval vector with NAs", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") int3 <- ymd(NA, quiet = TRUE) %--% ymd(NA, quiet = TRUE) ints <- c(int1, int2, int3) nas <- as.numeric(c(NA, NA, NA)) expect_equal(suppressMessages(ints / years(1)), c(1, 2, NA)) expect_equal(suppressMessages(ints / dyears(1)), c(1, 2, NA)) expect_equal(suppressMessages(ints / years(NA)), nas) expect_equal(suppressMessages(ints / dyears(NA)), nas) }) test_that("division operations work for period numerator", { int1 <- ymd("2009-01-01") %--% ymd("2010-01-01") expect_error(years(2) / int1) expect_equal(days(2) / hours(12), 4) expect_equal(years(1) / months(1), 12) expect_error(days(2) / dhours(12)) expect_error(days(1) / make_difftime(days = 1)) expect_equal(days(2) / 2, days(1)) }) test_that("division works for period numerator with vectors", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") expect_error(years(1:2) / int2) expect_error(years(1) / c(int1, int2)) expect_equal(days(1:2) / hours(12), c(2, 4)) expect_equal(days(1) / hours(c(12, 24)), c(2, 1)) expect_error(days(1:2) / dhours(12)) expect_error(days(1) / dhours(c(12, 24))) expect_error(days(1:2) / make_difftime(days = 1)) expect_equal(days(2) / c(1, 2), c(days(2), days(1))) expect_equal(days(c(2, 4)) / c(2), c(days(1), days(2))) }) test_that("division operations work for duration numerator", { int <- ymd("2009-12-01") %--% ymd("2010-01-01") expect_error(ddays(31)/int) expect_error(ddays(20)/ days(20)) expect_equal(ddays(20)/ ddays(1), 20) expect_equal(ddays(20)/ make_difftime(days = 1), 20) }) test_that("division works for duration numerator with vectors", { int1 <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") expect_error(ddays(365*c(1:2)) / int2) expect_error(ddays(365) / c(int1, int2)) expect_equal(ddays(1:2) / dhours(12), c(2, 4)) expect_equal(ddays(1) / dhours(c(12, 24)), c(2, 1)) expect_error(ddays(1:2) / hours(12)) expect_error(ddays(1) / hours(c(12, 24))) expect_equal(ddays(1:2) / make_difftime(days = 1), c(1, 2)) expect_equal(ddays(2) / c(1, 2), c(ddays(2), ddays(1))) expect_equal(ddays(c(2, 4)) / c(2), c(ddays(1), ddays(2))) }) test_that("division operations work for difftime numerator", { diff <- make_difftime(days = 365) int <- ymd("2010-01-01") %--% ymd("2011-01-01") expect_error(diff/int) expect_error(diff/days(1)) expect_equal(diff/ddays(365), 1) }) test_that("division works as expected for periods", { expect_that(3/months(1), throws_error()) expect_that(months(1)/3, throws_error()) expect_that(months(9)/3, equals(months(3))) expect_that(months(9)/3, is_a("Period")) }) test_that("dividing vectors works for periods", { expect_that(c(2, 3)/months(1), throws_error()) expect_that(months(1)/c(2, 3), throws_error()) expect_that(months(9)/c(3, 1), equals(months(c(3, 9)))) expect_that(months(9)/c(3, 1), is_a("Period")) }) test_that("division works as expected for durations", { expect_that(3/dhours(1), throws_error()) expect_that(dhours(9)/3, equals(dhours(3))) expect_that(dhours(9)/3, is_a("Duration")) }) test_that("dividing vectors works for durations", { expect_that(c(2, 3)/dhours(1), throws_error()) expect_that(dhours(9)/c(3, 1), equals(dhours(c(3, 9)))) expect_that(dhours(9)/c(3, 1), is_a("Duration")) }) lubridate/tests/testthat/test-round.R0000644000176200001440000006652713263104612017474 0ustar liggesuserscontext("Rounding") test_that("floor_date works for each time element", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(floor_date(x, "second"), as.POSIXct("2009-08-03 12:01:59", tz = "UTC")) expect_identical(floor_date(x, "minute"), as.POSIXct("2009-08-03 12:01:00", tz = "UTC")) expect_identical(floor_date(x, "hour"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "day"), as.POSIXct("2009-08-03 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "week"), as.POSIXct("2009-08-02 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "month"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "bimonth"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "quarter"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "halfyear"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "year"), as.POSIXct("2009-01-01 00:00:00", tz = "UTC")) }) test_that("floor_date and round_date throw on invalid multi-unit spec", { x <- ymd_hms("2009-08-03 12:01:57.11") expect_error(floor_date(x, "120 sec")) expect_error(floor_date(x, "120 min")) expect_error(floor_date(x, "25 h")) expect_error(floor_date(x, "32 days")) }) test_that("floor_date works for multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(floor_date(x, "2 secs"), as.POSIXct("2009-08-03 12:01:58", tz = "UTC")) expect_identical(floor_date(x, "2s"), as.POSIXct("2009-08-03 12:01:58", tz = "UTC")) expect_identical(floor_date(x, "2 mins"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "2M"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "2 hours"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "2h"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_identical(floor_date(x, "2 days"), as.POSIXct("2009-08-03 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "3 days"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "10 days"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "10d"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) ## expect_identical(floor_date(x, "2 week"), as.POSIXct("2009-08-xx 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "2 month"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "2m"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_identical(floor_date(x, "2 bimonth"), floor_date(x, "4 months")) expect_identical(floor_date(x, "2 quarter"), floor_date(x, "6 months")) expect_identical(floor_date(x, "2 halfyear"), floor_date(x, "year")) expect_identical(floor_date(x, "2 year"), as.POSIXct("2008-01-01 00:00:00", tz = "UTC")) }) test_that("floor_date works for fractional multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(floor_date(x, ".2 secs"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(floor_date(x, ".1s"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(floor_date(x, ".05s"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(floor_date(x, ".01s"), as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC")) expect_identical(floor_date(x, ".005s"), as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC")) expect_identical(floor_date(x, ".5 mins"), as.POSIXct("2009-08-03 12:01:30", tz = "UTC")) }) test_that("multi-unit rounding works the same for POSIX and Date objects", { px <- ymd("2009-08-01", tz = "UTC") dt <- ymd("2009-08-01") expect_identical(floor_date(px, "5 mins"), floor_date(dt, "5 mins")) expect_identical(floor_date(px, "5 mins"), floor_date(dt, "5 mins")) expect_identical(ceiling_date(px + 0.0001, "5 mins"), ceiling_date(dt, "5 mins")) expect_identical(ceiling_date(px, "5 mins", change_on_boundary = T), ceiling_date(dt, "5 mins", change_on_boundary = T)) expect_identical(ceiling_date(px + 0.001, "5 hours"), ceiling_date(dt, "5 hours")) expect_identical(ceiling_date(px + 0.0001, "5 hours", change_on_boundary = T), ceiling_date(dt, "5 hours", change_on_boundary = T)) expect_identical(ceiling_date(px + 0.001, "2 hours"), ceiling_date(dt, "2 hours")) expect_identical(as_date(floor_date(px, "2 days")), floor_date(dt, "2 days")) expect_identical(as_date(ceiling_date(px + 0.001, "2 days")), ceiling_date(dt, "2 days")) expect_identical(as_date(floor_date(px, "5 days")), floor_date(dt, "5 days")) expect_identical(as_date(ceiling_date(px + 0.001, "5 days")), ceiling_date(dt, "5 days")) expect_identical(as_date(floor_date(px, "2 months")), floor_date(dt, "2 months")) expect_identical(as_date(ceiling_date(px, "2 months")), ceiling_date(dt, "2 months")) expect_identical(as_date(floor_date(px, "5 months")), floor_date(dt, "5 months")) expect_identical(as_date(ceiling_date(px, "5 months")), ceiling_date(dt, "5 months")) }) test_that("ceiling_date works for multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") y <- as.POSIXct("2009-08-03 12:01:30.23", tz = "UTC") z <- as.POSIXct("2009-08-24 12:01:30.23", tz = "UTC") expect_identical(ceiling_date(x, "2 secs"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_identical(ceiling_date(x, "3 secs"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_identical(ceiling_date(x, "5 secs"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_identical(ceiling_date(y, "2 secs"), as.POSIXct("2009-08-03 12:01:32", tz = "UTC")) expect_identical(ceiling_date(y, "3 secs"), as.POSIXct("2009-08-03 12:01:33", tz = "UTC")) expect_identical(ceiling_date(y, "5 secs"), as.POSIXct("2009-08-03 12:01:35", tz = "UTC")) expect_identical(ceiling_date(x, "2 mins"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_identical(ceiling_date(x, "3 mins"), as.POSIXct("2009-08-03 12:03:00", tz = "UTC")) expect_identical(ceiling_date(x, "5 mins"), as.POSIXct("2009-08-03 12:05:00", tz = "UTC")) expect_identical(ceiling_date(x, "2 hours"), as.POSIXct("2009-08-03 14:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "3 hours"), as.POSIXct("2009-08-03 15:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "2 days"), as.POSIXct("2009-08-05 00:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "3 days"), as.POSIXct("2009-08-04 00:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "10 days"), as.POSIXct("2009-08-11 00:00:00", tz = "UTC")) expect_identical(ceiling_date(z, "5 days"), as.POSIXct("2009-08-26 00:00:00", tz = "UTC")) expect_identical(ceiling_date(z, "10 days"), as.POSIXct("2009-08-31 00:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "2 month"), as.POSIXct("2009-09-01 00:00:00", tz = "UTC")) expect_identical(ceiling_date(x, "2 bimonth"), ceiling_date(x, "4 months")) expect_identical(ceiling_date(x, "2 quarter"), ceiling_date(x, "6 months")) expect_identical(ceiling_date(x, "2 halfyear"), ceiling_date(x, "year")) expect_identical(ceiling_date(x, "2 year"), as.POSIXct("2010-01-01 00:00:00", tz = "UTC")) }) test_that("ceiling_date works for fractional multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(ceiling_date(x, ".2 secs"), as.POSIXct("2009-08-03 12:01:59.4", tz = "UTC")) expect_identical(ceiling_date(x, ".1s"), as.POSIXct("2009-08-03 12:01:59.3", tz = "UTC")) expect_identical(ceiling_date(x, ".05s"), as.POSIXct("2009-08-03 12:01:59.25", tz = "UTC")) expect_identical(ceiling_date(x, ".5 mins"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) }) test_that("round_date works for each time element", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_equal(round_date(x, "second"), as.POSIXct("2009-08-03 12:01:59", tz = "UTC")) expect_equal(round_date(x, "minute"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(round_date(x, "hour"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_equal(round_date(x, "day"), as.POSIXct("2009-08-04 00:00:00", tz = "UTC")) expect_equal(round_date(x, "week"), as.POSIXct("2009-08-02 00:00:00", tz = "UTC")) expect_equal(round_date(x, "month"), as.POSIXct("2009-08-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "bimonth"), as.POSIXct("2009-09-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "quarter"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "halfyear"), as.POSIXct("2009-07-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "year"), as.POSIXct("2010-01-01 00:00:00", tz = "UTC")) }) test_that("floor_date and ceiling_date work with leap years", { expect_equal(floor_date(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30")), "year"), ymd_hms(c("2016-01-01 0:0:0", "2016-01-01 0:0:0"))) expect_equal(floor_date(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30"), tz = "America/New_York"), "year"), ymd_hms(c("2016-01-01 0:0:0", "2016-01-01 0:0:0"), tz = "America/New_York")) expect_equal(ceiling_date(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30")), "year"), ymd_hms(c("2017-01-01 0:0:0", "2017-01-01 0:0:0"))) expect_equal(ceiling_date(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30"), tz = "America/New_York"), "year"), ymd_hms(c("2017-01-01 0:0:0", "2017-01-01 0:0:0"), tz = "America/New_York")) }) test_that("round_date works for multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_equal(round_date(x, "2 second"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(round_date(x, "2 minute"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(round_date(x, "3 mins"), as.POSIXct("2009-08-03 12:03:00", tz = "UTC")) expect_equal(round_date(x, "5 mins"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_equal(round_date(x, "2 hour"), as.POSIXct("2009-08-03 12:00:00", tz = "UTC")) expect_equal(round_date(x, "5 hour"), as.POSIXct("2009-08-03 10:00:00", tz = "UTC")) expect_equal(round_date(x, "2 days"), as.POSIXct("2009-08-03 00:00:00", tz = "UTC")) expect_equal(round_date(x, "2 months"), as.POSIXct("2009-09-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "bimonth"), round_date(x, "2 months")) expect_equal(round_date(x, "bimonth"), round_date(x, "4 months")) expect_equal(round_date(x, "quarter"), round_date(x, "3 months")) expect_equal(round_date(x, "halfyear"), round_date(x, "6 months")) expect_equal(round_date(x, "3 years"), as.POSIXct("2010-01-01 00:00:00", tz = "UTC")) expect_equal(round_date(x, "4 years"), as.POSIXct("2008-01-01 00:00:00", tz = "UTC")) }) test_that("round_date works for fractional multi-units", { x <- as.POSIXct("2009-08-03 12:01:59.23", tz = "UTC") expect_identical(round_date(x, ".2 secs"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(round_date(x, ".1s"), as.POSIXct("2009-08-03 12:01:59.2", tz = "UTC")) expect_identical(round_date(x, ".05s"), as.POSIXct("2009-08-03 12:01:59.25", tz = "UTC")) expect_identical(round_date(x, ".5 mins"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) }) test_that("floor_date handles vectors", { x <- as.POSIXct(c("2009-08-03 12:01:59.23", "2010-08-03 12:01:59.23"), tz = "UTC") expect_identical(floor_date(x, "second"), as.POSIXct(c("2009-08-03 12:01:59", "2010-08-03 12:01:59"), tz = "UTC")) expect_identical(floor_date(x, "minute"), as.POSIXct(c("2009-08-03 12:01:00", "2010-08-03 12:01:00"), tz = "UTC")) expect_identical(floor_date(x, "hour"), as.POSIXct(c("2009-08-03 12:00:00", "2010-08-03 12:00:00"), tz = "UTC")) expect_identical(floor_date(x, "day"), as.POSIXct(c("2009-08-03 00:00:00", "2010-08-03 00:00:00"), tz = "UTC")) expect_identical(floor_date(x, "week"), as.POSIXct(c("2009-08-02 00:00:00", "2010-08-01 00:00:00"), tz = "UTC")) expect_identical(floor_date(x, "month"), as.POSIXct(c("2009-08-01 00:00:00", "2010-08-01 00:00:00"), tz = "UTC")) expect_identical(floor_date(x, "year"), as.POSIXct(c("2009-01-01 00:00:00", "2010-01-01 00:00:00"), tz = "UTC")) }) test_that("ceiling_date handles vectors", { x <- as.POSIXct(c("2009-08-03 12:01:59.23", "2010-08-03 12:01:59.23"), tz = "UTC") expect_identical(ceiling_date(x, "second"), as.POSIXct(c("2009-08-03 12:02:00", "2010-08-03 12:02:00"), tz = "UTC")) expect_identical(ceiling_date(x, "minute"), as.POSIXct(c("2009-08-03 12:02:00", "2010-08-03 12:02:00"), tz = "UTC")) expect_identical(ceiling_date(x, "hour"), as.POSIXct(c("2009-08-03 13:00:00", "2010-08-03 13:00:00"), tz = "UTC")) expect_identical(ceiling_date(x, "day"), as.POSIXct(c("2009-08-04 00:00:00", "2010-08-04 00:00:00"), tz = "UTC")) expect_identical(ceiling_date(x, "week"), as.POSIXct(c("2009-08-09 00:00:00", "2010-08-08 00:00:00"), tz = "UTC")) expect_identical(ceiling_date(x, "month"), as.POSIXct(c("2009-09-01 00:00:00", "2010-09-01 00:00:00"), tz = "UTC")) expect_identical(ceiling_date(x, "year"), as.POSIXct(c("2010-01-01 00:00:00", "2011-01-01 00:00:00"), tz = "UTC")) }) test_that("round_date handles vectors", { x <- as.POSIXct(c("2009-08-03 12:01:59.23", "2010-08-03 12:01:59.23"), tz = "UTC") expect_identical(round_date(x, "second"), as.POSIXct(c("2009-08-03 12:01:59", "2010-08-03 12:01:59"), tz = "UTC")) expect_identical(round_date(x, "minute"), as.POSIXct(c("2009-08-03 12:02:00", "2010-08-03 12:02:00"), tz = "UTC")) expect_identical(round_date(x, "hour"), as.POSIXct(c("2009-08-03 12:00:00", "2010-08-03 12:00:00"), tz = "UTC")) expect_identical(round_date(x, "day"), as.POSIXct(c("2009-08-04 00:00:00", "2010-08-04 00:00:00"), tz = "UTC")) expect_identical(round_date(x, "week"), as.POSIXct(c("2009-08-02 00:00:00", "2010-08-01 00:00:00"), tz = "UTC")) expect_identical(round_date(x, "month"), as.POSIXct(c("2009-08-01 00:00:00", "2010-08-01 00:00:00"), tz = "UTC")) expect_identical(round_date(x, "year"), as.POSIXct(c("2010-01-01 00:00:00", "2011-01-01 00:00:00"), tz = "UTC")) }) test_that("floor_date works for a variety of formats", { x <- as.POSIXct("2009-08-03 12:01:59", tz = "UTC") expect_equal(floor_date(x, "minute"), as.POSIXct("2009-08-03 12:01:00", tz = "UTC")) expect_equal(floor_date(as.Date(x), "month"), as.Date("2009-08-01")) expect_equal(floor_date(as.Date(x), "bimonth"), ymd("2009-07-01")) expect_equal(floor_date(as.Date(x), "quarter"), ymd("2009-07-01")) expect_equal(floor_date(as.Date(x), "halfyear"), ymd("2009-07-01")) expect_equal(floor_date(as.POSIXlt(x), "minute"), as.POSIXlt(as.POSIXct("2009-08-03 12:01:00", tz = "UTC"))) }) test_that("ceiling_date works for a variety of formats", { x <- as.POSIXct("2009-08-03 12:01:59", tz = "UTC") expect_equal(ceiling_date(x, "minute"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(ceiling_date(as.Date(x), "month"), as.Date("2009-09-01")) expect_equal(ceiling_date(as.Date(x), "bimonth"), ymd("2009-09-01")) expect_equal(ceiling_date(as.Date(x), "quarter"), ymd("2009-10-01")) expect_equal(ceiling_date(as.Date(x), "halfyear"), ymd("2010-01-01")) expect_equal(ceiling_date(as.POSIXlt(x), "minute"), as.POSIXlt(as.POSIXct("2009-08-03 12:02:00", tz = "UTC"))) }) test_that("round_date works for a variety of formats", { x <- as.POSIXct("2009-08-03 12:01:59", tz = "UTC") expect_equal(round_date(x, "minute"), as.POSIXct("2009-08-03 12:02:00", tz = "UTC")) expect_equal(round_date(as.Date(x), "month"), as.Date("2009-08-01")) expect_equal(round_date(as.POSIXlt(x), "minute"), as.POSIXlt(as.POSIXct("2009-08-03 12:02:00", tz = "UTC"))) }) test_that("rounding works across DST", { ## https://github.com/hadley/lubridate/issues/399 tt <- ymd("2016-03-27", tz = "Europe/Helsinki"); expect_equal(ceiling_date(tt, "month"), as.POSIXct("2016-04-01", tz = "Europe/Helsinki")) expect_equal(ceiling_date(tt, "day"), as.POSIXct("2016-03-27", tz = "Europe/Helsinki")) tt <- ymd("2016-03-28", tz = "Europe/Helsinki"); expect_equal(floor_date(tt, "month"), as.POSIXct("2016-03-01", tz = "Europe/Helsinki")) tt <- ymd_hms("2016-03-27 05:00:00", tz = "Europe/Helsinki"); expect_equal(floor_date(tt, "day"), as.POSIXct("2016-03-27", tz = "Europe/Helsinki")) ## https://github.com/tidyverse/lubridate/issues/605 x <- ymd_hms("2017-11-05 23:59:03", tz = 'America/New_York') expect_equal(ceiling_date(x, "day"), as.POSIXct("2017-11-06", tz = "America/New_York")) }) test_that("Ceiling for partials (Date) rounds up on boundary", { expect_identical(ceiling_date(as.Date("2012-09-27"), "day"), ymd("2012-09-28")) expect_identical(ceiling_date(as.Date("2012-09-01"), "day"), ymd("2012-09-02")) expect_identical(ceiling_date(as.Date("2012-09-01"), "2 days"), ymd("2012-09-03")) }) test_that("Ceiling for Date returns date when unit level is higher than day", { expect_true(is.Date(ceiling_date(ymd("20160927"), "year"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "halfyear"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "quarter"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "bimonth"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "month"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "week"))) expect_true(is.Date(ceiling_date(ymd("20160927"), "day"))) expect_true(is.POSIXct(ceiling_date(ymd("20160927"), "hour"))) expect_true(is.POSIXct(ceiling_date(ymd("20160927"), "minute"))) expect_true(is.POSIXct(ceiling_date(ymd("20160927"), "second"))) }) test_that("Ceiling for POSIXct always returns POSIXct", { expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "year"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "halfyear"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "quarter"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "bimonth"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "month"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "week"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "day"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "hour"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "minute"))) expect_true(is.POSIXct(ceiling_date(ymd_hms("20160927 00:00:00"), "second"))) }) test_that("ceiling_date does not round up dates that are already on a boundary", { expect_equal(ceiling_date(ymd_hms("2012-09-01 00:00:00"), "month"), as.POSIXct("2012-09-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "year"), as.POSIXct("2012-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "2 year"), as.POSIXct("2012-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "3 year"), as.POSIXct("2013-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "5 year"), as.POSIXct("2015-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "second"), ymd_hms("2012-01-01 01:00:00")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "2 second"), ymd_hms("2012-01-01 01:00:00")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "2 second", change_on_boundary = T), ymd_hms("2012-01-01 01:00:02")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "5 second"), ymd_hms("2012-01-01 01:00:00")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "bimonth"), ymd_hms("2012-01-01 00:00:00")) }) test_that("ceiling_date does round up dates on a boundary with change_on_boundary=TRUE", { expect_equal(ceiling_date(as.Date("2012-09-27"), "day", TRUE), as.Date("2012-09-28")) expect_equal(ceiling_date(as.Date("2012-09-01"), "month", TRUE), as.Date("2012-10-01")) expect_equal(ceiling_date(ymd_hms("2012-09-01 00:00:00"), "month", TRUE), ymd("2012-10-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-09-01 00:00:00"), "bimonth", TRUE), ymd("2012-11-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "year", TRUE), as.POSIXct("2013-01-01", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "hour", TRUE), ymd_hms("2012-01-01 02:00:00")) expect_equal(ceiling_date(ymd_hms("2012-01-01 00:00:00"), "day", TRUE), ymd("2012-01-02", tz = "UTC")) expect_equal(ceiling_date(ymd_hms("2012-01-01 01:00:00"), "second", TRUE), ymd_hms("2012-01-01 01:00:01")) }) test_that("floor_date does not round down dates that are already on a boundary", { expect_equal(floor_date(as.Date("2012-09-27"), "day"), as.Date("2012-09-27")) }) test_that("round_date does not round dates that are already on a boundary", { expect_equal(round_date(as.Date("2012-09-27"), "day"), as.Date("2012-09-27")) }) test_that("ceiling_date returns input of length zero when given input of length zero", { x <- structure(vector(mode = "numeric"), class = c("POSIXct", "POSIXt")) expect_equal(ceiling_date(x), x) }) test_that("floor_date returns input of length zero when given input of length zero", { x <- structure(vector(mode = "numeric"), class = c("POSIXct", "POSIXt")) expect_equal(floor_date(x), x) }) test_that("round_date returns input of length zero when given input of length zero", { x <- structure(vector(mode = "numeric"), class = c("POSIXct", "POSIXt")) expect_equal(round_date(x), x) }) test_that("round_date behaves correctly on 60th second", { ## (bug #217) x <- ymd_hms("2013-12-01 23:59:59.9999") expect_equal(round_date(x, unit = "second"), ymd("2013-12-02", tz = "UTC")) second(x) <- 60 expect_equal(x, ymd("2013-12-02", tz = "UTC")) }) test_that("round_date and ceiling_date skip day time gap", { ## (#240) tz <- "Europe/Amsterdam" times <- ymd_hms("2013-03-31 01:00:00 CET", "2013-03-31 01:15:00 CEST", "2013-03-31 01:30:00 CEST", "2013-03-31 01:45:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:15:00 CEST", tz = tz) round <- ymd_hms("2013-03-31 01:00:00 CET", "2013-03-31 01:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", tz = tz) expect_equal(round_date(times, "hour"), round) ceiling <- ymd_hms("2013-03-31 01:00:00 CET", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 03:00:00 CEST", "2013-03-31 04:00:00 CEST", tz = tz) expect_equal(ceiling_date(times, "hour"), ceiling) tz <- "America/Chicago" x <- ymd_hms(c("2014-03-09 00:00:00", "2014-03-09 00:29:59", "2014-03-09 00:30:00", "2014-03-09 00:59:59", "2014-03-09 01:35:00", "2014-03-09 03:15:00", "2014-11-02 00:30:00", "2014-11-02 00:59:59", "2014-11-02 01:35:00", "2014-11-02 02:15:00", "2014-11-02 02:45:00"), tz = tz) y <- as.POSIXct(c("2014-03-09 00:00:00", "2014-03-09 00:00:00", "2014-03-09 01:00:00", "2014-03-09 01:00:00", "2014-03-09 03:00:00", "2014-03-09 03:00:00", "2014-11-02 01:00:00", "2014-11-02 01:00:00", "2014-11-02 02:00:00", "2014-11-02 02:00:00", "2014-11-02 03:00:00"), tz = tz) expect_equal(round_date(x, "hour"), y) }) test_that("ceiling_date, round_date and floor_date behave correctly with NA", { ## (bug #486) x <- ymd_hms("2009-08-03 12:01:59.23", tz = "UTC") + (0:1)*days() x[2] <- NA expect_equal(ceiling_date(x, unit = "day"), ymd(c("2009-08-04", NA), tz = "UTC")) expect_equal(ceiling_date(x, unit = "seconds"), ymd_hms(c("2009-08-03 12:02:00", NA), tz = "UTC")) expect_equal(ceiling_date(x, unit = "months"), ymd(c("2009-09-01", NA), tz = "UTC")) expect_equal(floor_date(x, unit = "day"), ymd(c("2009-08-03", NA), tz = "UTC")) expect_equal(floor_date(x, unit = "months"), ymd(c("2009-08-01", NA), tz = "UTC")) expect_equal(round_date(x, unit = "minute"), ymd_hms(c("2009-08-03 12:02:00", NA), tz = "UTC")) }) test_that("floor_date works for seasons", { dts <- ymd_hms(sprintf("2017-%d-02 0:34:3", 1:12)) expect_equal(month(floor_date(dts, "season")), c(12, 12, 3, 3, 3, 6, 6, 6, 9, 9, 9, 12)) dts <- force_tz(dts, "America/New_York") expect_equal(month(floor_date(dts, "season")), c(12, 12, 3, 3, 3, 6, 6, 6, 9, 9, 9, 12)) }) test_that("ceiling_date works for seasons", { dts <- ymd_hms(sprintf("2017-%d-02 0:34:3", 1:12)) expect_equal(month(ceiling_date(dts, "season")), c(3, 3, 6, 6, 6, 9, 9, 9, 12, 12, 12, 3)) dts <- force_tz(dts, "America/New_York") expect_equal(month(ceiling_date(dts, "season")), c(3, 3, 6, 6, 6, 9, 9, 9, 12, 12, 12, 3)) }) test_that("round on week respects week_start", { date <- ymd("2017-05-07") ## sunday ct <- as.POSIXct("2010-02-03 13:45:59", tz = "America/New_York", format = "%Y-%m-%d %H:%M:%S") ## Wednesday expect_equal(wday(floor_date(ct, "week", week_start = 1)), 2) expect_equal(wday(floor_date(ct, "week", week_start = 2)), 3) expect_equal(wday(floor_date(ct, "week", week_start = 5)), 6) expect_equal(wday(floor_date(ct, "week", week_start = 7)), 1) expect_equal(wday(floor_date(date, "week", week_start = 1)), 2) expect_equal(wday(floor_date(date, "week", week_start = 2)), 3) expect_equal(wday(floor_date(date, "week", week_start = 5)), 6) expect_equal(wday(floor_date(date, "week", week_start = 7)), 1) expect_equal(wday(floor_date(ct, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(floor_date(ct, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(floor_date(ct, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(floor_date(ct, "week", week_start = 7), week_start = 7), 1) expect_equal(wday(floor_date(date, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(floor_date(date, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(floor_date(date, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(floor_date(date, "week", week_start = 7), week_start = 7), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 1)), 2) expect_equal(wday(ceiling_date(ct, "week", week_start = 2)), 3) expect_equal(wday(ceiling_date(ct, "week", week_start = 5)), 6) expect_equal(wday(ceiling_date(ct, "week", week_start = 7)), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 1)), 2) expect_equal(wday(ceiling_date(date, "week", week_start = 2)), 3) expect_equal(wday(ceiling_date(date, "week", week_start = 5)), 6) expect_equal(wday(ceiling_date(date, "week", week_start = 7)), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(ceiling_date(ct, "week", week_start = 7), week_start = 7), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 1), week_start = 1), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 2), week_start = 2), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 5), week_start = 5), 1) expect_equal(wday(ceiling_date(date, "week", week_start = 7), week_start = 7), 1) }) lubridate/tests/testthat/test-settors.R0000644000176200001440000007433013236356705020053 0ustar liggesuserscontext("Settors") test_that("seconds settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) second(poslt) <- 10 second(posct) <- 10 second(date) <- 10 expect_that(second(poslt), equals(10)) expect_that(second(posct), equals(10)) expect_that(second(date), equals(10)) }) test_that("seconds settor rolls over as expected", { poslt <- as.POSIXlt("2010-12-31 23:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) second(poslt) <- 69 second(posct) <- 69 second(date) <- 69 expect_that(second(poslt), equals(9)) expect_that(minute(poslt), equals(0)) expect_that(hour(poslt), equals(0)) expect_that(mday(poslt), equals(1)) expect_that(wday(poslt), equals(7)) expect_that(yday(poslt), equals(1)) expect_that(month(poslt), equals(1)) expect_that(year(poslt), equals(2011)) expect_that(tz(poslt), equals("UTC")) expect_that(second(posct), equals(9)) expect_that(minute(posct), equals(0)) expect_that(hour(posct), equals(0)) expect_that(mday(posct), equals(1)) expect_that(wday(posct), equals(7)) expect_that(yday(posct), equals(1)) expect_that(month(posct), equals(1)) expect_that(year(posct), equals(2011)) expect_that(tz(posct), equals("UTC")) expect_that(second(date), equals(9)) expect_that(minute(date), equals(1)) expect_that(hour(date), equals(0)) expect_that(mday(date), equals(31)) expect_that(wday(date), equals(6)) expect_that(yday(date), equals(365)) expect_that(month(date), equals(12)) expect_that(year(date), equals(2010)) expect_that(tz(date), equals("UTC")) }) test_that("seconds settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) second(poslt) <- 1 second(posct) <- 1 second(date) <- 1 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") second(poslt) <- 69 second(posct) <- 69 second(date) <- 69 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("seconds settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2010-03-14 01:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posxct <- as.POSIXct(poslt) second(poslt) <- 69 second(posxct) <- 69 expect_true(is.na(poslt)) expect_true(is.na(posxct)) }) test_that("seconds settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) second(poslt) <- 10 second(posct) <- 10 day(date) <- 10 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) second(poslt) <- 70 second(posct) <- 70 day(date) <- 32 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) }) test_that("minutes settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) minute(poslt) <- 10 minute(posct) <- 10 minute(date) <- 10 expect_that(minute(poslt), equals(10)) expect_that(minute(posct), equals(10)) expect_that(minute(date), equals(10)) }) test_that("minutes settor rolls over as expected", { poslt <- as.POSIXlt("2010-12-31 23:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) minute(poslt) <- 69 minute(posct) <- 69 minute(date) <- 69 expect_that(second(poslt), equals(59)) expect_that(minute(poslt), equals(9)) expect_that(hour(poslt), equals(0)) expect_that(mday(poslt), equals(1)) expect_that(wday(poslt), equals(7)) expect_that(yday(poslt), equals(1)) expect_that(month(poslt), equals(1)) expect_that(year(poslt), equals(2011)) expect_that(tz(poslt), equals("UTC")) expect_that(second(posct), equals(59)) expect_that(minute(posct), equals(9)) expect_that(hour(posct), equals(0)) expect_that(mday(posct), equals(1)) expect_that(wday(posct), equals(7)) expect_that(yday(posct), equals(1)) expect_that(month(posct), equals(1)) expect_that(year(posct), equals(2011)) expect_that(tz(posct), equals("UTC")) expect_that(second(date), equals(0)) expect_that(minute(date), equals(9)) expect_that(hour(date), equals(1)) expect_that(mday(date), equals(31)) expect_that(wday(date), equals(6)) expect_that(yday(date), equals(365)) expect_that(month(date), equals(12)) expect_that(year(date), equals(2010)) expect_that(tz(date), equals("UTC")) }) test_that("minutes settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) minute(poslt) <- 1 minute(posct) <- 1 minute(date) <- 1 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") minute(poslt) <- 70 minute(posct) <- 70 minute(date) <- 70 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("minutes settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2010-03-14 01:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posct <- as.POSIXct(poslt) minute(poslt) <- 70 minute(posct) <- 70 expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("minutes settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) minute(poslt) <- 1 minute(posct) <- 1 minute(date) <- 1 expect_that("minute<-"(poslt, 1), is_a("POSIXlt")) expect_that("minute<-"(posct, 1), is_a("POSIXct")) expect_that("minute<-"(date, 1), is_a("POSIXlt")) minute(poslt) <- 70 minute(posct) <- 70 minute(date) <- 70 expect_that("minute<-"(poslt, 70), is_a("POSIXlt")) expect_that("minute<-"(posct, 70), is_a("POSIXct")) expect_that("minute<-"(date, 70), is_a("POSIXlt")) }) test_that("hours settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) hour(poslt) <- 10 hour(posct) <- 10 hour(date) <- 10 expect_that(hour(poslt), equals(10)) expect_that(hour(posct), equals(10)) expect_that(hour(date), equals(10)) }) test_that("hours settor rolls over as expected", { poslt <- as.POSIXlt("2010-12-31 23:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) hour(poslt) <- 25 hour(posct) <- 25 hour(date) <- 25 expect_that(second(poslt), equals(59)) expect_that(minute(poslt), equals(59)) expect_that(hour(poslt), equals(1)) expect_that(mday(poslt), equals(1)) expect_that(wday(poslt), equals(7)) expect_that(yday(poslt), equals(1)) expect_that(month(poslt), equals(1)) expect_that(year(poslt), equals(2011)) expect_that(tz(poslt), equals("UTC")) expect_that(second(posct), equals(59)) expect_that(minute(posct), equals(59)) expect_that(hour(posct), equals(1)) expect_that(mday(posct), equals(1)) expect_that(wday(posct), equals(7)) expect_that(yday(posct), equals(1)) expect_that(month(posct), equals(1)) expect_that(year(posct), equals(2011)) expect_that(tz(posct), equals("UTC")) expect_that(second(date), equals(0)) expect_that(minute(date), equals(0)) expect_that(hour(date), equals(1)) expect_that(mday(date), equals(1)) expect_that(wday(date), equals(7)) expect_that(yday(date), equals(1)) expect_that(month(date), equals(01)) expect_that(year(date), equals(2011)) expect_that(tz(date), equals("UTC")) }) test_that("hours settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) hour(poslt) <- 1 hour(posct) <- 1 hour(date) <- 1 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") hour(poslt) <- 70 hour(posct) <- 70 hour(date) <- 70 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("hours settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2010-03-14 01:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posct <- as.POSIXct(poslt) hour(poslt) <- 2 hour(posct) <- 2 expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("hours settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) hour(poslt) <- 2 hour(posct) <- 2 hour(date) <- 2 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("POSIXlt")) hour(poslt) <- 25 hour(posct) <- 25 hour(date) <- 25 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("POSIXlt")) }) test_that("mdays settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) mday(poslt) <- 10 mday(posct) <- 10 mday(date) <- 10 expect_that(mday(poslt), equals(10)) expect_that(mday(posct), equals(10)) expect_that(mday(date), equals(10)) expect_that(yday(poslt), equals(41)) expect_that(yday(posct), equals(41)) expect_that(yday(date), equals(41)) expect_that(wday(poslt), equals(4)) expect_that(wday(posct), equals(4)) expect_that(wday(date), equals(4)) }) test_that("mdays settor rolls over as expected", { poslt <- as.POSIXlt("2010-12-31 23:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) mday(poslt) <- 32 mday(posct) <- 32 mday(date) <- 32 expect_that(second(poslt), equals(59)) expect_that(minute(poslt), equals(59)) expect_that(hour(poslt), equals(23)) expect_that(mday(poslt), equals(1)) expect_that(wday(poslt), equals(7)) expect_that(yday(poslt), equals(1)) expect_that(month(poslt), equals(1)) expect_that(year(poslt), equals(2011)) expect_that(tz(poslt), equals("UTC")) expect_that(second(posct), equals(59)) expect_that(minute(posct), equals(59)) expect_that(hour(posct), equals(23)) expect_that(mday(posct), equals(1)) expect_that(wday(posct), equals(7)) expect_that(yday(posct), equals(1)) expect_that(month(posct), equals(1)) expect_that(year(posct), equals(2011)) expect_that(tz(posct), equals("UTC")) expect_that(second(date), equals(0)) expect_that(minute(date), equals(0)) expect_that(hour(date), equals(0)) expect_that(mday(date), equals(1)) expect_that(wday(date), equals(7)) expect_that(yday(date), equals(1)) expect_that(month(date), equals(1)) expect_that(year(date), equals(2011)) expect_that(tz(date), equals("UTC")) }) test_that("mdays settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) mday(poslt) <- 1 mday(posct) <- 1 mday(date) <- 1 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") mday(poslt) <- 32 mday(posct) <- 32 mday(date) <- 32 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("mdays settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2010-03-13 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posct <- as.POSIXct(poslt) mday(poslt) <- 14 mday(posct) <- 14 expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("mdays settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) mday(poslt) <- 3 mday(posct) <- 3 mday(date) <- 3 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) mday(poslt) <- 32 mday(posct) <- 32 mday(date) <- 32 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) }) test_that("ydays settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) yday(poslt) <- 41 yday(posct) <- 41 yday(date) <- 41 expect_that(yday(poslt), equals(41)) expect_that(yday(posct), equals(41)) expect_that(yday(date), equals(41)) expect_that(mday(poslt), equals(10)) expect_that(mday(posct), equals(10)) expect_that(mday(date), equals(10)) expect_that(wday(poslt), equals(4)) expect_that(wday(posct), equals(4)) expect_that(wday(date), equals(4)) }) test_that("ydays settor rolls over as expected", { poslt <- as.POSIXlt("2010-12-31 23:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) yday(poslt) <- 366 yday(posct) <- 366 yday(date) <- 366 expect_that(second(poslt), equals(59)) expect_that(minute(poslt), equals(59)) expect_that(hour(poslt), equals(23)) expect_that(mday(poslt), equals(1)) expect_that(wday(poslt), equals(7)) expect_that(yday(poslt), equals(1)) expect_that(month(poslt), equals(1)) expect_that(year(poslt), equals(2011)) expect_that(tz(poslt), equals("UTC")) expect_that(second(posct), equals(59)) expect_that(minute(posct), equals(59)) expect_that(hour(posct), equals(23)) expect_that(mday(posct), equals(1)) expect_that(wday(posct), equals(7)) expect_that(yday(posct), equals(1)) expect_that(month(posct), equals(1)) expect_that(year(posct), equals(2011)) expect_that(tz(posct), equals("UTC")) expect_that(second(date), equals(0)) expect_that(minute(date), equals(0)) expect_that(hour(date), equals(0)) expect_that(mday(date), equals(1)) expect_that(wday(date), equals(7)) expect_that(yday(date), equals(1)) expect_that(month(date), equals(1)) expect_that(year(date), equals(2011)) expect_that(tz(date), equals("UTC")) }) test_that("ydays settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) yday(poslt) <- 1 yday(posct) <- 1 yday(date) <- 1 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") yday(poslt) <- 366 yday(posct) <- 366 yday(date) <- 366 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("ydays settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2010-03-13 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posct <- as.POSIXct(poslt) yday(poslt) <- 73 yday(posct) <- 73 expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("ydays settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) yday(poslt) <- 3 yday(posct) <- 3 yday(date) <- 3 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) yday(poslt) <- 366 yday(posct) <- 366 yday(date) <- 366 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) }) test_that("wdays settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) wday(poslt) <- 5 wday(posct) <- 5 wday(date) <- 5 expect_that(wday(poslt), equals(5)) expect_that(wday(posct), equals(5)) expect_that(wday(date), equals(5)) expect_that(mday(poslt), equals(4)) expect_that(mday(posct), equals(4)) expect_that(mday(date), equals(4)) expect_that(mday(poslt), equals(4)) expect_that(mday(posct), equals(4)) expect_that(mday(date), equals(4)) }) test_that("wdays settor rolls over as expected", { poslt <- as.POSIXlt("2010-12-31 23:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) wday(poslt) <- 8 wday(posct) <- 8 wday(date) <- 8 expect_that(second(poslt), equals(59)) expect_that(minute(poslt), equals(59)) expect_that(hour(poslt), equals(23)) expect_that(mday(poslt), equals(2)) expect_that(wday(poslt), equals(1)) expect_that(yday(poslt), equals(2)) expect_that(month(poslt), equals(1)) expect_that(year(poslt), equals(2011)) expect_that(tz(poslt), equals("UTC")) expect_that(second(posct), equals(59)) expect_that(minute(posct), equals(59)) expect_that(hour(posct), equals(23)) expect_that(mday(posct), equals(2)) expect_that(wday(posct), equals(1)) expect_that(yday(posct), equals(2)) expect_that(month(posct), equals(1)) expect_that(year(posct), equals(2011)) expect_that(tz(posct), equals("UTC")) expect_that(second(date), equals(0)) expect_that(minute(date), equals(0)) expect_that(hour(date), equals(0)) expect_that(mday(date), equals(2)) expect_that(wday(date), equals(1)) expect_that(yday(date), equals(2)) expect_that(month(date), equals(1)) expect_that(year(date), equals(2011)) expect_that(tz(date), equals("UTC")) }) test_that("wdays settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) wday(poslt) <- 2 wday(posct) <- 2 wday(date) <- 2 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") wday(poslt) <- 8 wday(posct) <- 8 wday(date) <- 8 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("wdays settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2010-03-13 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posct <- as.POSIXct(poslt) wday(poslt) <- 8 wday(posct) <- 8 expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("wdays settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) wday(poslt) <- 3 wday(posct) <- 3 wday(date) <- 3 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) wday(poslt) <- 8 wday(posct) <- 8 wday(date) <- 8 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) }) test_that("months settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) month(poslt) <- 5 month(posct) <- 5 month(date) <- 5 expect_that(month(poslt), equals(5)) expect_that(month(posct), equals(5)) expect_that(month(date), equals(5)) }) test_that("months settor rolls over as expected", { poslt <- as.POSIXlt("2010-12-31 23:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) month(poslt) <- 13 month(posct) <- 13 month(date) <- 13 expect_that(second(poslt), equals(59)) expect_that(minute(poslt), equals(59)) expect_that(hour(poslt), equals(23)) expect_that(mday(poslt), equals(31)) expect_that(wday(poslt), equals(2)) expect_that(yday(poslt), equals(31)) expect_that(month(poslt), equals(1)) expect_that(year(poslt), equals(2011)) expect_that(tz(poslt), equals("UTC")) expect_that(second(posct), equals(59)) expect_that(minute(posct), equals(59)) expect_that(hour(posct), equals(23)) expect_that(mday(posct), equals(31)) expect_that(wday(posct), equals(2)) expect_that(yday(posct), equals(31)) expect_that(month(posct), equals(1)) expect_that(year(posct), equals(2011)) expect_that(tz(posct), equals("UTC")) expect_that(second(date), equals(0)) expect_that(minute(date), equals(0)) expect_that(hour(date), equals(0)) expect_that(mday(date), equals(31)) expect_that(wday(date), equals(2)) expect_that(yday(date), equals(31)) expect_that(month(date), equals(1)) expect_that(year(date), equals(2011)) expect_that(tz(date), equals("UTC")) }) test_that("months settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) month(poslt) <- 1 month(posct) <- 1 month(date) <- 1 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") month(poslt) <- 13 month(posct) <- 13 month(date) <- 13 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("months settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2010-02-14 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posct <- as.POSIXct(poslt) month(poslt) <- 3 month(posct) <- 3 expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("months settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) month(poslt) <- 1 month(posct) <- 1 month(date) <- 1 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) month(poslt) <- 13 month(posct) <- 13 month(date) <- 13 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) }) test_that("years settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) year(poslt) <- 2000 year(posct) <- 2000 year(date) <- 2000 expect_that(year(poslt), equals(2000)) expect_that(year(posct), equals(2000)) expect_that(year(date), equals(2000)) }) test_that("years settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) year(poslt) <- 2000 year(posct) <- 2000 year(date) <- 2000 expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("years settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2009-03-14 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posct <- as.POSIXct(poslt) year(poslt) <- 2010 year(posct) <- 2010 expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("years settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) year(poslt) <- 2000 year(posct) <- 2000 year(date) <- 2000 expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) }) test_that("dates settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) date(poslt) <- as.Date("2000-01-01") date(posct) <- as.Date("2000-01-01") date(date) <- as.Date("2000-01-01") expect_that(date(poslt), equals(as.Date("2000-01-01"))) expect_that(date(posct), equals(as.Date("2000-01-01"))) expect_that(date(date), equals(as.Date("2000-01-01"))) }) test_that("dates settor does not change time zone", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) date(poslt) <- as.Date("2000-01-01") date(posct) <- as.Date("2000-01-01") date(date) <- as.Date("2000-01-01") expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("dates settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2009-03-14 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") posct <- as.POSIXct(poslt) date(poslt) <- as.Date("2010-03-14") date(posct) <- as.Date("2010-03-14") expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("dates settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) date(poslt) <- as.Date("2000-01-01") date(posct) <- as.Date("2000-01-01") date(date) <- as.Date("2000-01-01") expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) }) test_that("time zone settor correctly performs simple updates", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) tz(poslt) <- "GMT" tz(posct) <- "GMT" tz(date) <- "GMT" # dates do not have a tz attribute expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "UTC") }) test_that("time zone settor returns NA for spring dst gap", { poslt <- as.POSIXlt("2010-03-14 02:30:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) tz(poslt) <- "America/New_York" tz(posct) <- "America/New_York" expect_that(is.na(poslt), is_true()) expect_that(is.na(posct), is_true()) }) test_that("time zone settor retains object class", { poslt <- as.POSIXlt("2010-02-14 01:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) tz(poslt) <- "GMT" tz(posct) <- "GMT" tz(date) <- "GMT" expect_that(poslt, is_a("POSIXlt")) expect_that(posct, is_a("POSIXct")) expect_that(date, is_a("Date")) }) test_that("settors handle vectors", { poslt <- as.POSIXlt(c("2010-02-14 01:59:59", "2010-02-15 01:59:59", "2010-02-16 01:59:59"), tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) second(poslt) <- 1 second(posct) <- 1 second(date) <- 1 expect_that(second(poslt), equals(c(1, 1, 1))) expect_that(second(posct), equals(c(1, 1, 1))) expect_that(second(date), equals(c(1, 1, 1))) minute(poslt) <- 1 minute(posct) <- 1 minute(date) <- 1 expect_that(minute(poslt), equals(c(1, 1, 1))) expect_that(minute(posct), equals(c(1, 1, 1))) expect_that(minute(date), equals(c(1, 1, 1))) hour(poslt) <- 1 hour(posct) <- 1 hour(date) <- 1 expect_that(hour(poslt), equals(c(1, 1, 1))) expect_that(hour(posct), equals(c(1, 1, 1))) expect_that(hour(date), equals(c(1, 1, 1))) mday(poslt) <- 1 mday(posct) <- 1 mday(date) <- 1 expect_that(mday(poslt), equals(c(1, 1, 1))) expect_that(mday(posct), equals(c(1, 1, 1))) expect_that(mday(date), equals(c(1, 1, 1))) wday(poslt) <- 1 wday(posct) <- 1 wday(date) <- 1 expect_that(wday(poslt), equals(c(1, 1, 1))) expect_that(wday(posct), equals(c(1, 1, 1))) expect_that(wday(date), equals(c(1, 1, 1))) yday(poslt) <- 1 yday(posct) <- 1 yday(date) <- 1 expect_that(yday(poslt), equals(c(1, 1, 1))) expect_that(yday(posct), equals(c(1, 1, 1))) expect_that(yday(date), equals(c(1, 1, 1))) week(poslt) <- 2 week(posct) <- 2 week(date) <- 2 expect_that(week(poslt), equals(c(2, 2, 2))) expect_that(week(posct), equals(c(2, 2, 2))) expect_that(week(date), equals(c(2, 2, 2))) month(poslt) <- 10 month(posct) <- 10 month(date) <- 10 expect_that(month(poslt), equals(c(10, 10, 10))) expect_that(month(posct), equals(c(10, 10, 10))) expect_that(month(date), equals(c(10, 10, 10))) year(poslt) <- 2001 year(posct) <- 2001 year(date) <- 2001 expect_that(year(poslt), equals(c(2001, 2001, 2001))) expect_that(year(posct), equals(c(2001, 2001, 2001))) expect_that(year(date), equals(c(2001, 2001, 2001))) date(poslt) <- as.Date("2001-01-01") date(posct) <- as.Date("2001-01-01") date(date) <- as.Date("2001-01-01") expect_that(date(poslt), equals(as.Date(c("2001-01-01", "2001-01-01", "2001-01-01")))) expect_that(date(posct), equals(as.Date(c("2001-01-01", "2001-01-01", "2001-01-01")))) expect_that(date(date), equals(as.Date(c("2001-01-01", "2001-01-01", "2001-01-01")))) tz(poslt) <- "GMT" tz(posct) <- "GMT" tz(date) <- "GMT" # date has been made POSIXlt with sec, etc expect_match(tz(poslt), "GMT") expect_match(tz(posct), "GMT") expect_match(tz(date), "GMT") }) test_that("qdays settors correctly performs simple updates and rolls over as expected", { poslt <- as.POSIXlt(c("2010-02-14 01:59:59", "2010-04-15 01:59:59", "2010-10-16 01:59:59"), tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) qday(poslt) <- 2 qday(posct) <- 2 qday(date) <- 2 expect_equal(month(poslt), c(1, 4, 10)) expect_equal(month(posct), c(1, 4, 10)) expect_equal(month(date), c(1, 4, 10)) expect_equal(mday(poslt), c(2, 2, 2)) expect_equal(mday(posct), c(2, 2, 2)) expect_equal(mday(date), c(2, 2, 2)) qday(poslt) <- 95 qday(posct) <- 95 qday(date) <- 95 expect_equal(month(poslt), c(4, 7, 1)) expect_equal(month(posct), c(4, 7, 1)) expect_equal(month(date), c(4, 7, 1)) expect_equal(mday(poslt), c(5, 4, 3)) expect_equal(mday(posct), c(5, 4, 3)) expect_equal(mday(date), c(5, 4, 3)) expect_equal(year(poslt), c(2010, 2010, 2011)) expect_equal(year(posct), c(2010, 2010, 2011)) expect_equal(year(date), c(2010, 2010, 2011)) }) lubridate/tests/testthat/test-ops-modulo.R0000644000176200001440000000536213201152061020422 0ustar liggesuserscontext("Modulo operations") test_that("modulo operations return correct class", { int <- ymd("2010-01-01") %--% ymd("2011-01-01") expect_error(int %% int) expect_is(int %% months(1), "Interval") expect_is(int %% ddays(10), "Interval") expect_error(months(3) %% int) expect_is(days(3) %% hours(2), "Period") expect_error(days(5) %% dminutes(300)) expect_error(dyears(3) %% int) expect_error(ddays(2) %% weeks(1)) expect_is(ddays(3) %% ddays(1), "Duration") }) test_that("modulo operations synchronize with integer division", { int <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- interval(int_start(int) + int %/% years(2) * years(2), int_end(int)) int3 <- interval(int_start(int) + int %/% dweeks(20) * dweeks(20), int_end(int)) expect_error(int %% int) expect_equal(int %% years(2), int2) expect_equal(int %% dweeks(20), int3) expect_error(years(2) %% int) expect_equal(years(2) %% months(5) + years(2) %/% months(5) * months(5), years(2)) expect_error(years(2) %% dweeks(20)) expect_error(dweeks(20) %% int) expect_error(dweeks(20) %% years(2)) expect_equal(dweeks(20) %% ddays(20) + dweeks(20) %/% ddays(20) * ddays(20), dweeks(20)) }) test_that("modulo operations work for vectors", { int <- ymd("2010-01-01") %--% ymd("2011-01-01") int2 <- ymd("2009-01-01") %--% ymd("2011-01-01") int3 <- interval(int_start(int) + int %/% years(2) * years(2), int_end(int)) int4 <- interval(int_start(int) + int %/% dweeks(20) * dweeks(20), int_end(int)) expect_error(c(int, int) %% int2) expect_equal(c(int, int) %% years(2), c(int3, int3)) expect_equal(c(int, int) %% dweeks(20), c(int4, int4)) expect_error(int %% c(int2, int2)) expect_equal(int %% years(c(2, 2)), c(int3, int3)) expect_equal(int %% dweeks(c(20, 20)), c(int4, int4)) expect_error(years(2:3) %% int) expect_equal(years(2:3) %% months(5) + years(2:3) %/% months(5) * months(5), years(2:3)) expect_error(years(2:3) %% dweeks(20)) expect_error(years(2) %% c(int, int)) expect_equal(years(2) %% months(5:6) + years(2) %/% months(5:6) * months(5:6), years(c(2, 2))) expect_error(years(2) %% dweeks(20:21)) expect_error(dweeks(20:21) %% int) expect_error(dweeks(20:21) %% years(2)) expect_equal(dweeks(20:21) %% ddays(20) + dweeks(20:21) %/% ddays(20) * ddays(20), dweeks(20:21)) expect_error(dweeks(20) %% c(int, int)) expect_error(dweeks(20) %% years(2:3)) expect_equal(dweeks(20) %% ddays(20:21) + dweeks(20) %/% ddays(20:21) * ddays(20:21), c(dweeks(20), dweeks(20))) }) lubridate/tests/testthat/test-ops-multiplication.R0000644000176200001440000000266213201152061022160 0ustar liggesuserscontext("Multiplication operations") # multiplication for everything test_that("multiplication throws error for instants", { x <- as.POSIXct("2010-03-15 00:00:00", tz = "UTC") expect_that(3 * x, throws_error()) }) test_that("multiplication throws error for intervals", { time1 <- as.POSIXct("2008-08-03 00:00:00", tz = "UTC") time2 <- as.POSIXct("2009-08-03 00:00:00", tz = "UTC") int <- interval(time1, time2) diff <- difftime(time2, time1) int2 <- interval(time1, time1 + 2*diff) expect_that(2*int, equals(int2)) }) test_that("multiplication works as expected for periods", { expect_that(3*months(1), equals(months(3))) expect_that(3*months(1), is_a("Period")) }) test_that("multiplying vectors works for periods", { expect_that(c(2, 3)*months(1), equals(months(2:3))) expect_that(c(2, 3)*months(1), is_a("Period")) }) test_that("multiplication works as expected for durations", { expect_that(3*dhours(1), equals(dhours(3))) expect_that(3*dhours(1), is_a("Duration")) }) test_that("multiplying vectors works for durations", { expect_that(c(2, 3)*dhours(1), equals(dhours(2:3))) expect_that(c(2, 3)*dhours(1), is_a("Duration")) }) test_that("make_difftime makes a correct difftime object", { x <- as.POSIXct("2008-01-01 12:00:00", tz = "UTC") y <- difftime(x + 3600, x) attr(y, "tzone") <- NULL expect_that(make_difftime(3600), equals(y)) expect_that(make_difftime(3600), is_a("difftime")) }) lubridate/tests/testthat/test-timezones.R0000644000176200001440000001240213237336235020352 0ustar liggesuserscontext("Time zones") test_that("with_tz works as expected", { x <- as.POSIXct("2008-08-03 10:01:59", tz = "America/New_York") y <- as.POSIXlt(x) expect_that(with_tz(x, "UTC"), equals(as.POSIXct(format( as.POSIXct(x), tz = "UTC"), tz = "UTC"))) expect_that(with_tz(y, "UTC"), equals(as.POSIXlt(format( as.POSIXct(x), tz = "UTC"), tz = "UTC"))) }) test_that("with_tz handles vectors", { x <- as.POSIXct(c("2008-08-03 13:01:59", "2009-08-03 10:01:59"), tz = "America/New_York") y <- as.POSIXlt(x) expect_that(with_tz(x, "UTC"), equals(as.POSIXct(format( as.POSIXct(x), tz = "UTC"), tz = "UTC"))) expect_that(with_tz(y, "UTC"), equals(as.POSIXlt(format( as.POSIXct(x), tz = "UTC"), tz = "UTC"))) }) test_that("with_tz handles various date-time classes", { x <- as.POSIXct("2008-08-03 13:01:59", tz = "America/New_York") expect_equal(with_tz(as.POSIXlt(x), "UTC"), as.POSIXlt(format(as.POSIXct(x), tz = "UTC"), tz = "UTC")) }) test_that("with_tz handles data.frames", { x <- as.POSIXct("2008-08-03 10:01:59", tz = "America/New_York") df <- data.frame(x = x, y = as.POSIXlt(x), z = "blabla") df <- with_tz(df, "UTC") x_out <- as.POSIXct(format(as.POSIXct(x), tz = "UTC"), tz = "UTC") expect_that(df$x, equals(x_out)) expect_that(df$y, equals(x_out)) }) test_that("force_tzs works as expected", { x <- ymd_hms(c("2009-08-07 00:00:01", "2009-08-07 00:00:01")) expect_equal(force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam")), ymd_hms("2009-08-07 04:00:01 UTC", "2009-08-06 22:00:01 UTC")) expect_equal(force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam"), tzone_out = "America/New_York"), ymd_hms("2009-08-07 00:00:01 EDT", "2009-08-06 18:00:01 EDT", tz = "America/New_York")) ## recycling expect_equal(force_tzs(x, tzones = "America/New_York", tzone_out = "UTC"), ymd_hms("2009-08-07 04:00:01 UTC", "2009-08-07 04:00:01 UTC")) x <- ymd_hms("2009-08-07 00:00:01") expect_equal(force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam")), ymd_hms("2009-08-07 04:00:01 UTC", "2009-08-06 22:00:01 UTC")) expect_equal(force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam"), tzone_out = "America/New_York"), ymd_hms("2009-08-07 00:00:01 EDT", "2009-08-06 18:00:01 EDT", tz = "America/New_York")) }) test_that("force_tzs is robusts against overflow", { x <- ymd_hms(c("2038-01-19 03:14:06", "2038-01-19 03:14:07", "2038-01-19 03:14:08", "2038-01-19 03:14:09", "2038-01-19 03:14:10")) expect_equal(force_tzs(x, tzones = "America/New_York"), with_tz(ymd_hms(c("2038-01-19 03:14:06", "2038-01-19 03:14:07", "2038-01-19 03:14:08", "2038-01-19 03:14:09", "2038-01-19 03:14:10"), tz = "America/New_York"), "UTC")) }) test_that("local_time works as expected", { x <- ymd_hms(c("2009-08-07 01:02:03", "2009-08-07 10:20:30")) expect_equal(local_time(x, units = "secs"), as.difftime(c(3723, 37230), units = "secs")) expect_equal(local_time(x, units = "hours"), as.difftime(c(3723, 37230)/3600, units = "hours")) expect_equal(local_time(x, "Europe/Amsterdam"), local_time(with_tz(x, "Europe/Amsterdam"))) x <- ymd_hms("2009-08-07 01:02:03") expect_equal(local_time(x, c("America/New_York", "Europe/Amsterdam", "Asia/Shanghai")), c(local_time(with_tz(x, "America/New_York")), local_time(with_tz(x, "Europe/Amsterdam")), local_time(with_tz(x, "Asia/Shanghai")))) }) test_that("with_tz throws warning on unrecognized time zones", { expect_warning(with_tz(now(), "blablabla")) expect_silent(with_tz(now(), "UTC")) expect_silent(with_tz(now(), "")) expect_silent(with_tz(now(), "America/New_York")) }) test_that("force_tz works as expected", { x <- as.POSIXct("2008-08-03 10:01:59", tz = "America/New_York") expect_that(force_tz(x, "UTC"), equals(as.POSIXct(format(as.POSIXct(x)), tz = "UTC"))) }) test_that("force_tz handles vectors", { x <- as.POSIXct(c("2008-08-03 13:01:59", "2009-08-03 10:01:59"), tz = "America/New_York") expect_that(force_tz(x, "UTC"), equals(as.POSIXct(format(as.POSIXct(x)), tz = "UTC"))) }) test_that("force_tz handles various date-time classes", { x <- as.POSIXct("2008-12-03 13:01:59", tz = "America/New_York") expect_equal(force_tz(as.POSIXlt(x), "UTC"), as.POSIXlt(format(x), tz = "UTC")) }) test_that("force_tz handles data.frames", { x <- as.POSIXct("2008-08-03 10:01:59", tz = "America/New_York") x_out <- as.POSIXct(format(as.POSIXct(x)), tz = "UTC") df <- data.frame(x = x, y = as.POSIXlt(x), z = "blabla") df <- force_tz(df, "UTC") expect_that(df$x, equals(x_out)) expect_that(df$y, equals(x_out)) }) test_that("force_tz doesn't return NA just because new time zone uses DST", { poslt <- as.POSIXlt("2009-03-14 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt2 <- force_tz(poslt, tz = "America/New_York") expect_true(!is.na(poslt2)) }) ## test_that("olson_time_zones returns a non-trivial character vector", { ## tz_olson <- olson_time_zones() ## expect_true(length(tz_olson) > 0) ## expect_is(tz_olson, "character") ## }) lubridate/tests/testthat/test-accessors.R0000644000176200001440000003262213236356705020333 0ustar liggesuserscontext("Accessors") test_that("seconds accessor extracts correct second", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(second(poslt), equals(59)) expect_that(second(posct), equals(59)) expect_that(second(date), equals(0)) }) test_that("minutes accessor extracts correct minute", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(minute(poslt), equals(45)) expect_that(minute(posct), equals(45)) expect_that(minute(date), equals(0)) }) test_that("hours accessor extracts correct hour", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(hour(poslt), equals(13)) expect_that(hour(posct), equals(13)) expect_that(hour(date), equals(0)) }) test_that("days accessors extract correct days", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(day(poslt), equals(3)) expect_that(day(posct), equals(3)) expect_that(day(date), equals(3)) expect_that(mday(poslt), equals(3)) expect_that(mday(posct), equals(3)) expect_that(mday(date), equals(3)) expect_that(yday(poslt), equals(34)) expect_that(yday(posct), equals(34)) expect_that(yday(date), equals(34)) expect_that(wday(poslt), equals(4)) expect_that(wday(posct), equals(4)) expect_that(wday(date), equals(4)) expect_that(qday(poslt), equals(34)) expect_that(qday(poslt), equals(34)) expect_that(qday(poslt), equals(34)) }) test_that("empty argument date() works", { expect_silent(date()) }) test_that("day accessors work on character inputs", { x <- "2017-05-07 GMT" d <- ymd(x) expect_equal(wday(x), wday(d)) expect_equal(mday(x), mday(d)) expect_equal(qday(x), qday(d)) expect_equal(yday(x), yday(d)) }) test_that("wday works with various start values", { days <- days2 <- ymd(c("2005-01-01", "2005-01-02", "2005-12-31", "2007-01-01", "2007-12-30", "2007-12-31", "2008-01-01", "2008-12-28", "2008-12-29", "2008-12-30", "2008-12-31", "2009-01-01", "2009-12-31", "2010-01-01", "2010-01-02")) expect_equal(as.character(wday(days, label = T, week_start = 1)), as.character(wday(days, label = T, week_start = 3))) expect_equal(as.character(wday(days, label = T, week_start = 1)), as.character(wday(days, label = T, week_start = 7))) expect_equal(as.character(wday(days, label = T, locale = "C"))[1], "Sat") expect_equal(as.character(wday(days, label = T, abbr = FALSE, locale = "C"))[1], "Saturday") expect_equal(wday(days, label = F, week_start = 1), c(6, 7, 6, 1, 7, 1, 2, 7, 1, 2, 3, 4, 4, 5, 6)) expect_equal(wday(days, label = F, week_start = 7), c(7, 1, 7, 2, 1, 2, 3, 1, 2, 3, 4, 5, 5, 6, 7)) set.seed(1000) new_days <- sample(1:7, length(days2), replace = T) wday(days2, week_start = 1) <- new_days expect_equal(wday(days2, week_start = 1), new_days) wday(days2, week_start = 7) <- new_days expect_equal(wday(days2, week_start = 7), new_days) wday(days2, week_start = 3) <- new_days expect_equal(wday(days2, week_start = 3), new_days) }) test_that("weeks accessor extracts correct week", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(week(poslt), equals(5)) expect_that(week(posct), equals(5)) expect_that(week(date), equals(5)) }) test_that("isoweek accessor extracts correct ISO8601 week", { poslt <- as.POSIXlt("2010-01-01 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(isoweek(poslt), equals(53)) expect_that(isoweek(posct), equals(53)) expect_that(isoweek(date), equals(53)) df <- read.table(textConnection( "Sat 1 Jan 2005 2005-01-01 2004-W53-6 Sun 2 Jan 2005 2005-01-02 2004-W53-7 Sat 31 Dec 2005 2005-12-31 2005-W52-6 Mon 1 Jan 2007 2007-01-01 2007-W01-1 Both years 2007 start with the same day. Sun 30 Dec 2007 2007-12-30 2007-W52-7 Mon 31 Dec 2007 2007-12-31 2008-W01-1 Tue 1 Jan 2008 2008-01-01 2008-W01-2 Gregorian year 2008 is a leap year. ISO year 2008 is 2 days shorter: 1 day longer at the start, 3 days shorter at the end. Sun 28 Dec 2008 2008-12-28 2008-W52-7 ISO year 2009 begins three days before the end of Gregorian 2008. Mon 29 Dec 2008 2008-12-29 2009-W01-1 Tue 30 Dec 2008 2008-12-30 2009-W01-2 Wed 31 Dec 2008 2008-12-31 2009-W01-3 Thu 1 Jan 2009 2009-01-01 2009-W01-4 Thu 31 Dec 2009 2009-12-31 2009-W53-4 ISO year 2009 has 53 weeks and ends three days into Gregorian year 2010. Fri 1 Jan 2010 2010-01-01 2009-W53-5 Sat 2 Jan 2010 2010-01-02 2009-W53-6 Sun 3 Jan 2010 2010-01-03 2009-W53-7"), sep = "\t", fill = T, stringsAsFactors = F, header = F) names(df) <- c("Gregorian", "ymd", "iso", "note") df <- within(df, { ymd <- ymd(ymd) isoweek <- as.numeric(gsub(".*W([0-9]+).*", "\\1", iso)) isoyear <- as.numeric(gsub("^([0-9]+).*", "\\1", iso)) }) expect_equal(isoweek(df$ymd), df$isoweek) expect_equal(isoyear(df$ymd), df$isoyear) }) test_that("epiweek computes dates correctly", { df <- read.table(textConnection( "ew date year 1 12/30/07 8 2 01/06/08 8 3 01/13/08 8 52 01/02/10 9 1 01/03/10 10 2 01/10/10 10 3 01/17/10 10 4 01/24/10 10 5 01/31/10 10 1 01/04/09 9 2 01/11/09 9 3 01/18/09 9 50 12/13/09 9 51 12/20/09 9 52 12/27/09 9 50 12/12/10 10 51 12/19/10 10 52 12/26/10 10 50 12/07/08 8 51 12/14/08 8 52 12/21/08 8"), header = T, sep = "\t", stringsAsFactors = F) date <- mdy(df$date) expect_equal(epiweek(date), df$ew) expect_equal(epiyear(date), df$year + 2000) }) test_that("isoweek returns correct value for non-UTC time zone (#311)", { cest <- ymd_hms("2015-04-14 16:45:00", tz = "Europe/Copenhagen") utc <- ymd_hms("2015-04-14 16:45:00", tz = "UTC") expect_equal(isoweek(cest), 16L) expect_equal(isoweek(utc), 16L) }) test_that("months accessor extracts correct month", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(month(poslt), equals(2)) expect_that(month(posct), equals(2)) expect_that(month(date), equals(2)) expect_that(as.character(month(date, label = TRUE, locale = "C")), equals("Feb")) expect_that(as.character(month(date, label = TRUE, abbr = FALSE, locale = "C")), equals("February")) }) test_that("quarters accessor extracts correct quarter", { posct <- ymd_hms("2010-11-03 13:45:59") poslt <- as.POSIXlt(posct) date <- as.Date(poslt) expect_that(quarter(poslt), equals(4)) expect_that(quarter(poslt, with_year = TRUE), equals(2010.4)) expect_that(quarter(poslt, fiscal_start = 11), equals(1)) expect_that(quarter(poslt, with_year = TRUE, fiscal_start = -2), equals(2011.1)) expect_that(quarter(poslt, with_year = TRUE, fiscal_start = 11), equals(2011.1)) expect_that(quarter(posct), equals(4)) expect_that(quarter(posct, with_year = TRUE), equals(2010.4)) expect_that(quarter(posct, fiscal_start = 11), equals(1)) expect_that(quarter(posct, with_year = TRUE, fiscal_start = -2), equals(2011.1)) expect_that(quarter(posct, with_year = TRUE, fiscal_start = 11), equals(2011.1)) expect_that(quarter(date), equals(4)) expect_that(quarter(date, with_year = TRUE), equals(2010.4)) expect_that(quarter(date, fiscal_start = 11), equals(1)) expect_that(quarter(date, with_year = TRUE, fiscal_start = -2), equals(2011.1)) expect_that(quarter(date, with_year = TRUE, fiscal_start = 11), equals(2011.1)) }) test_that("years accessor extracts correct year", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(year(poslt), equals(2010)) expect_that(year(posct), equals(2010)) expect_that(year(date), equals(2010)) }) test_that("isoyear accessor extracts correct ISO8601 year", { poslt <- c(as.POSIXlt("2014-12-28 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S"), as.POSIXlt("2014-12-29 01:12:08", tz = "UTC", format = "%Y-%m-%d %H:%M:%S")) posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(isoyear(poslt), equals(c(2014, 2015))) expect_that(isoyear(posct), equals(c(2014, 2015))) expect_that(isoyear(date), equals(c(2014, 2015))) }) test_that("date accessor extracts correct date", { poslt <- as.POSIXlt("2010-02-03 23:45:59", tz = "Etc/GMT+8", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(date(poslt), equals(as.Date("2010-02-03"))) expect_that(date(posct), equals(as.Date("2010-02-03"))) expect_that(date(date), equals(as.Date("2010-02-03"))) }) test_that("timezone accessor extracts correct timezone", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_match(tz(poslt), "UTC") expect_match(tz(posct), "UTC") expect_match(tz(date), "UTC") }) test_that("accessors handle vectors", { poslt <- as.POSIXlt(c("2001-01-01 01:01:01", "2002-02-02 02:02:02", "2003-03-03 03:03:03"), tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(second(poslt), equals(c(1, 2, 3))) expect_that(second(posct), equals(c(1, 2, 3))) expect_that(second(date), equals(c(0, 0, 0))) expect_that(minute(poslt), equals(c(1, 2, 3))) expect_that(minute(posct), equals(c(1, 2, 3))) expect_that(minute(date), equals(c(0, 0, 0))) expect_that(hour(poslt), equals(c(1, 2, 3))) expect_that(hour(posct), equals(c(1, 2, 3))) expect_that(hour(date), equals(c(0, 0, 0))) expect_that(mday(poslt), equals(c(1, 2, 3))) expect_that(mday(posct), equals(c(1, 2, 3))) expect_that(mday(date), equals(c(1, 2, 3))) expect_that(wday(poslt), equals(c(2, 7, 2))) expect_that(wday(posct), equals(c(2, 7, 2))) expect_that(wday(date), equals(c(2, 7, 2))) expect_that(yday(poslt), equals(c(1, 33, 62))) expect_that(yday(posct), equals(c(1, 33, 62))) expect_that(yday(date), equals(c(1, 33, 62))) expect_that(week(poslt), equals(c(1, 5, 9))) expect_that(week(posct), equals(c(1, 5, 9))) expect_that(week(date), equals(c(1, 5, 9))) expect_that(isoweek(poslt), equals(c(1, 5, 10))) expect_that(isoweek(posct), equals(c(1, 5, 10))) expect_that(isoweek(date), equals(c(1, 5, 10))) expect_that(month(poslt), equals(c(1, 2, 3))) expect_that(month(posct), equals(c(1, 2, 3))) expect_that(month(date), equals(c(1, 2, 3))) expect_that(year(poslt), equals(c(2001, 2002, 2003))) expect_that(year(posct), equals(c(2001, 2002, 2003))) expect_that(year(date), equals(c(2001, 2002, 2003))) expect_that(date(poslt), equals(as.Date(c("2001-01-01", "2002-02-02", "2003-03-03")))) expect_that(date(posct), equals(as.Date(c("2001-01-01", "2002-02-02", "2003-03-03")))) expect_that(date(date), equals(as.Date(c("2001-01-01", "2002-02-02", "2003-03-03")))) expect_match(tz(poslt), "UTC") expect_match(tz(posct), "UTC") expect_match(tz(date), "UTC") }) test_that("accessors handle Period objects", { per <- period(seconds = 1, minutes = 2, hours = 3, days = 4, months = 5, years = 6) pers <- c(per, per) expect_equal(second(per), 1) expect_equal(minute(per), 2) expect_equal(hour(per), 3) expect_equal(day(per), 4) expect_equal(month(per), 5) expect_equal(year(per), 6) expect_error(date(per), "date is undefined for Period objects") expect_equal(second(pers), c(1, 1)) expect_equal(minute(pers), c(2, 2)) expect_equal(hour(pers), c(3, 3)) expect_equal(day(pers), c(4, 4)) expect_equal(month(pers), c(5, 5)) expect_equal(year(pers), c(6, 6)) expect_error(date(pers), "date is undefined for Period objects") second(per) <- 2 minute(per) <- 3 hour(per) <- 4 day(per) <- 5 month(per) <- 6 year(per) <- 7 expect_equal(per@.Data, 2) expect_equal(per@minute, 3) expect_equal(per@hour, 4) expect_equal(per@day, 5) expect_equal(per@month, 6) expect_equal(per@year, 7) second(pers) <- c(2, 3) minute(pers) <- c(3, 4) hour(pers) <- c(4, 5) day(pers) <- c(5, 6) month(pers) <- c(6, 7) year(pers) <- c(7, 8) expect_equal(pers@.Data, c(2, 3)) expect_equal(pers@minute, c(3, 4)) expect_equal(pers@hour, c(4, 5)) expect_equal(pers@day, c(5, 6)) expect_equal(pers@month, c(6, 7)) expect_equal(pers@year, c(7, 8)) }) context("Test days_in_month") test_that( "days in month works for non leap years", { x <- seq(ymd("2011-01-01"), ymd("2011-12-01"), "1 month") expected <- c( Jan = 31L, Feb = 28L, Mar = 31L, Apr = 30L, May = 31L, Jun = 30L, Jul = 31L, Aug = 31L, Sep = 30L, Oct = 31L, Nov = 30L, Dec = 31L ) expect_that(days_in_month(x), equals(expected)) } ) test_that( "days in month works for leap years", { x <- seq(ymd("2012-01-01"), ymd("2012-12-01"), "1 month") expected <- c( Jan = 31L, Feb = 29L, Mar = 31L, Apr = 30L, May = 31L, Jun = 30L, Jul = 31L, Aug = 31L, Sep = 30L, Oct = 31L, Nov = 30L, Dec = 31L ) expect_that(days_in_month(x), equals(expected)) } ) lubridate/tests/testthat/test-durations.R0000644000176200001440000001763413236356705020364 0ustar liggesuserscontext("Durations") test_that("duration constructor doesn't accept non-numeric or non-character inputs", { expect_error(duration(interval(ymd("2014-01-01"), ymd("2015-01-01")))) }) test_that("make_difftime works as expected", { x <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") y <- difftime(x + 5 + 30*60 + 60*60 + 14*24*60*60, x, tz = "UTC") attr(y, "tzone") <- NULL diff <- make_difftime(seconds = 5, minutes = 30, days = 0, hour = 1, weeks = 2) expect_that(diff, equals(y)) }) test_that("Duration parsing works", { expect_equal(duration("1min 2sec 2secs 1H 2M 1d"), duration(seconds = 4, minutes = 3, hours = 1, days = 1)) expect_equal(duration("day day"), duration(days = 2)) expect_equal(duration("S M H d w"), duration(seconds = 1, minutes = 1, hours = 1, days = 1, weeks = 1)) expect_equal(duration("1S 2M 3H 4d 5w"), duration(seconds = 1, minutes = 2, hours = 3, days = 4, weeks = 5)) }) test_that("fractional parsing works as expected", { expect_equal(duration("1.1min 2.3sec 2.3secs 1.0H 2.2M 1.5d"), duration(seconds = 43222.6, minutes = 3, hours = 1, days = 1)) expect_equal(duration("day 1.2days"), duration(days = 2, seconds = 17280)) }) test_that("sub-unit fractional parsing works as expected", { expect_identical(duration(".1min .3sec .3secs .0H .2M .5d"), duration("0.1min 0.3sec 0.3secs 0.0H 0.2M 0.5d")) expect_identical(duration(".1min .3sec .3secs .0H .2M .5d"), duration(seconds = 6.6, minutes = .2, hours = 12)) }) test_that("parsing with 0 units works as expected", { expect_equal(as.numeric(duration("2d 0H 0M 1s")), 2*24*3600 + 1) expect_equal(as.numeric(duration("0d 0H 0M 1s")), 1) expect_equal(period("2d 0H 0M 1s"), days(2) + seconds(1)) expect_equal(period("y 0m 2d 0H 0M 1s"), years(1) + days(2) + seconds(1)) }) test_that("make_difftime handles vectors", { x <- as.POSIXct(c("2008-08-03 13:01:59", "2008-08-03 13:01:59"), tz = "UTC") y <- difftime(x + c(5 + 30*60 + 60*60 + 14*24*60*60, 1 + 3*24*60*60 + 60*60), x, tz = "UTC") attr(y, "tzone") <- NULL z <- difftime(x + c(5 + 30*60 + 60*60 + 14*24*60*60, 5 + 30*60 + 60*60 + 14*24*60*60 + 3*24*60*60), x, tz = "UTC") attr(z, "tzone") <- NULL expect_that(make_difftime(seconds = c(5, 1), minutes = c(30, 0), days = c(0, 3), hour = c(1, 1), weeks = c(2, 0)), equals(y)) expect_that(make_difftime(seconds = 5, minutes = 30, days = c(0, 3), hour = 1, weeks = 2), equals(z)) }) test_that("duration works as expected", { dur <- duration(seconds = 5, minutes = 30, days = 0, hour = 1, weeks = 2) expect_equal(dur@.Data, 1215005) expect_is(dur, "Duration") }) test_that("duration handles vectors", { dur1 <- duration(seconds = c(5, 1), minutes = c(30, 0), days = c(0, 3), hour = c(1, 1), weeks = c(2, 0)) dur2 <- duration(seconds = 5, minutes = 30, days = c(0, 3), hour = 1, weeks = 2) expect_equal(dur1@.Data, c(1215005, 262801)) expect_equal(dur2@.Data, c(1215005, 1474205)) expect_is(dur1, "Duration") expect_is(dur2, "Duration") }) test_that("as.duration handles vectors", { expect_that(as.duration(minutes(1:3)), equals(dminutes(1:3))) }) test_that("as.duration handles periods", { expect_that(as.duration(seconds(1)), equals(dseconds(1))) expect_that(as.duration(minutes(2)), equals(dminutes(2))) expect_that(as.duration(hours(3)), equals(dhours(3))) expect_that(as.duration(days(4)), equals(ddays(4))) expect_that(as.duration(weeks(5)), equals(dweeks(5))) expect_that(as.duration(months(1)), equals(dseconds(60*60*24*365.25/12))) expect_that(as.duration(years(1)), equals(dseconds(60*60*24*365.25))) expect_that(as.duration(seconds(1) + minutes(4)), equals(dseconds(1) + dminutes(4))) }) test_that("as.duration handles intervals", { time1 <- as.POSIXct("2009-01-02 12:24:03", tz = "UTC") time2 <- as.POSIXct("2010-02-03 14:31:42", tz = "UTC") dur <- as.duration(interval(time1, time2)) y <- as.numeric(time2 - time1, units = "secs") expect_equal(dur@.Data, y) expect_is(dur, "Duration") }) test_that("as.duration handles difftimes", { x <- difftime(as.POSIXct("2010-02-03 14:31:42", tz = "UTC"), as.POSIXct("2009-01-02 12:24:03", tz = "UTC")) dur <- as.duration(x) y <- as.numeric(x, units = "secs") expect_equal(dur@.Data, y) expect_is(dur, "Duration") }) test_that("eobjects handle vectors", { dur <- dseconds(c(1, 3, 4)) expect_equal(dur@.Data, c(1, 3, 4)) expect_is(dur, "Duration") }) test_that("is.duration works as expected", { ct_time <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") lt_time <- as.POSIXlt("2009-08-03 13:01:59", tz = "UTC") expect_that(is.duration(234), is_false()) expect_that(is.duration(ct_time), is_false()) expect_that(is.duration(lt_time), is_false()) expect_that(is.duration(Sys.Date()), is_false()) expect_that(is.duration(minutes(1)), is_false()) expect_that(is.duration(dminutes(1)), is_true()) expect_that(is.duration(make_difftime(1000)), is_false()) expect_that(is.duration(interval(lt_time, ct_time)), is_false()) }) test_that("is.duration handle vectors", { expect_that(is.duration(dminutes(1:3)), is_true()) }) test_that("format.Duration correctly displays intervals of length 0", { dur <- duration(seconds = 5) expect_output(print(dur[FALSE]), "Duration\\(0)") }) test_that("format.Duration correctly displays durations with an NA", { dur <- duration(seconds = c(5, NA)) expect_equivalent(format(dur), c("5s", NA)) }) test_that("summary.Duration creates useful summary", { dur <- dminutes(5) text <- c(rep("300s (~5 minutes)", 6), 1) names(text) <- c("Min.", "1st Qu.", "Median", "Mean", "3rd Qu.", "Max.", "NA's") expect_equal(summary(c(dur, NA)), text) }) test_that("format.Duration works with NA values", { expect_equal(format(duration(c(NA, 1, 100, 10000, 100000, 100000000, 75.25, 75.5001))), c(NA, "1s", "100s (~1.67 minutes)", "10000s (~2.78 hours)", "1e+05s (~1.16 days)", "1e+08s (~3.17 years)", "75.25s (~1.25 minutes)", "75.5001s (~1.26 minutes)")) expect_equal(format(duration(c(75.25, 75.5001))), c("75.25s (~1.25 minutes)", "75.5001s (~1.26 minutes)")) }) test_that("as.duration handles NA interval objects", { one_missing_date <- as.POSIXct(NA_real_, origin = origin) one_missing_interval <- interval(one_missing_date, one_missing_date) several_missing_dates <- rep(as.POSIXct(NA_real_, origin = origin), 2) several_missing_intervals <- interval(several_missing_dates, several_missing_dates) start_missing_intervals <- interval(several_missing_dates, origin) end_missing_intervals <- interval(origin, several_missing_dates) na.dur <- dseconds(NA) expect_equal(as.duration(one_missing_interval), na.dur) expect_equal(as.duration(several_missing_intervals), c(na.dur, na.dur)) expect_equal(as.duration(start_missing_intervals), c(na.dur, na.dur)) expect_equal(as.duration(end_missing_intervals), c(na.dur, na.dur)) }) test_that("as.duration handles NA period objects", { na.dur <- dseconds(NA) expect_equal(suppressMessages(as.duration(years(NA))), na.dur) expect_equal(suppressMessages(as.duration(years(c(NA, NA)))), c(na.dur, na.dur)) expect_equal(suppressMessages(as.duration(years(c(1, NA)))), c(dyears(1) + ddays(.25), na.dur)) }) test_that("as.duration handles NA objects", { na.dur <- dseconds(NA) expect_equal(as.duration(NA), na.dur) }) test_that("Comparison operators work duration and difftime objects (#323)", { t1 <- now() t2 <- t1 + dhours(1) t3 <- t1 + dseconds(1) expect_true((t2 - t1) > dseconds(60)) expect_false((t2 - t1) > dseconds(3600)) expect_true((t2 - t1) < dseconds(3601)) expect_true(dhours(1) > dminutes(59)) expect_true(dhours(1) == dseconds(3600)) expect_error(dhours(1) == 3600) expect_error(dhours(1) == 1) }) lubridate/tests/testthat/test-POSIXt.R0000644000176200001440000000534413201152061017412 0ustar liggesuserscontext("POSIXt") test_that("is.POSIXt works as expected", { expect_that(is.POSIXt(234), is_false()) expect_that(is.POSIXt(as.POSIXct("2008-08-03 13:01:59", tz = "UTC")), is_true()) expect_that(is.POSIXt(as.POSIXlt("2008-08-03 13:01:59", tz = "UTC")), is_true()) expect_that(is.POSIXt(Sys.Date()), is_false()) expect_that(is.POSIXt(minutes(1)), is_false()) expect_that(is.POSIXt(dminutes(1)), is_false()) expect_that(is.POSIXt(interval( as.POSIXct("2008-08-03 13:01:59", tz = "UTC"), as.POSIXct("2009-08-03 13:01:59", tz = "UTC"))), is_false()) }) test_that("is.POSIXt handles vectors", { expect_that(is.POSIXt(c( as.POSIXct("2008-08-03 13:01:59", tz = "UTC"), as.POSIXct("2009-08-03 13:01:59", tz = "UTC"))), is_true()) }) # as_datetime ------------------------------------------------------------- test_that("converts numeric", { dt <- as_datetime(0) expect_s3_class(dt, "POSIXct") expect_equal(tz(dt), "UTC") expect_equal(unclass(dt)[[1]], 0) }) test_that("converts date", { dt <- as_datetime(as.Date("1970-01-01")) expect_s3_class(dt, "POSIXct") expect_equal(tz(dt), "UTC") expect_equal(unclass(dt)[[1]], 0) }) test_that("converts character", { chars <- c("2017-03-22T15:48:00.000Z", "2017-03-01 0:0:0", "2017-03-01 0:0:0.23", "2017-03-01 0:0:0.23") dt <- as_datetime(chars) expect_s3_class(dt, "POSIXct") expect_equal(tz(dt), "UTC") expect_equal(dt, ymd_hms(chars)) expect_equal(as_datetime(chars, tz = "Europe/Amsterdam"), ymd_hms(chars, tz = "Europe/Amsterdam", quiet = TRUE)) }) test_that("changes timezone of POSIXct", { dt <- as_datetime(make_datetime(tz = "America/Chicago")) expect_equal(tz(dt), "UTC") }) test_that("addition of large seconds doesn't overflow", { from_period <- origin + seconds(2 ^ 31 + c(-2:2)) from_char <- ymd_hms(c("2038-01-19 03:14:06", "2038-01-19 03:14:07", "2038-01-19 03:14:08", "2038-01-19 03:14:09", "2038-01-19 03:14:10")) expect_equal(from_period, from_char) }) test_that("as_datetime works correctly", { x <- c("17-01-20", "2017-01-20 01:02:03", "2017-03-22T15:48:00.000Z", "2017-01-20", "2017-01-20 01:02:03", "2017-03-22T15:48:00.000Z") y <- c("2017-01-20 00:00:00 UTC", "2017-01-20 01:02:03 UTC", "2017-03-22 15:48:00 UTC", "2017-01-20 00:00:00 UTC", "2017-01-20 01:02:03 UTC", "2017-03-22 15:48:00 UTC") zns <- c(3, 6) putc <- ymd_hms(y) pus <- ymd_hms(y[-zns], tz = "America/Chicago") expect_equal(as_datetime(x), putc) expect_equal(as_datetime(x[-zns], tz = "America/Chicago"), pus) for (i in seq_along(x)) { expect_equal(as_datetime(x[[i]]), putc[[i]]) } for (i in seq_along(pus)) { expect_equal(as_datetime(x[-zns][[i]], tz = "America/Chicago"), pus[[i]]) } }) lubridate/tests/testthat/test-decimal-date.R0000644000176200001440000000367313236356705020663 0ustar liggesuserscontext("Decimal_date") test_that("decimal_date handles vectors", { x <- as.POSIXct(c("2008-08-03 13:01:59", "2009-08-03 10:01:59"), tz = "UTC") expect_that(round(decimal_date(x), 3), equals(c(2008.589, 2009.587))) }) test_that("decimal_date handles first second of year without returning NaN", { expect_equal(decimal_date(ymd("2012-01-01")), 2012) }) test_that("date_decimal works as expected", { y <- 2008.58846 expect_equal(as.numeric(date_decimal(y)), 1217754118) }) test_that("date_decimal handles vectors", { y <- c(2008.589, 2009.587) expect_equal(as.numeric(date_decimal(y)), c(1217771194, 1249279632)) }) test_that("date_decimal reverses decimal_date", { date <- ymd("2012-03-01", tz = "UTC") decimal <- decimal_date(date) expect_equal(date_decimal(decimal), date) date2 <- ymd("2012-03-01") decimal2 <- decimal_date(date2) expect_equal(as.Date(date_decimal(decimal2)), date2) ## before day light shift date3 <- ymd_hms("2008-02-03 10:01:59", tz = "America/New_York") decimal3 <- decimal_date(date3) date_decimal(decimal3, tz = "America/New_York") expect_equal(date_decimal(decimal3, tz = "America/New_York"), date3) ## after date <- ymd_hms("2008-05-03 10:01:59", tz = "America/New_York") decimal <- decimal_date(date) date_decimal(decimal, tz = "America/New_York") expect_equal(date_decimal(decimal, tz = "America/New_York"), date) }) test_that("decimal_date returns NA on NA date input", { expect_equal(decimal_date(as.Date(NA)), as.numeric(NA)) }) test_that("decimal_date correctly handles daylight savings time", { date4 <- ymd_hms("2016-03-13 01:00:00", tz = "America/New_York") date4 <- date4 + dhours(-1:1) decimal4 <- decimal_date(date4) expect_equal(c(2016.196721, 2016.1968351, 2016.196948), decimal4) diff.decimal <- diff(decimal4) expect_equal(diff.decimal[1], diff.decimal[2]) expect_equal(c(2016.197290, 2016.197404, 2016.1975182), decimal_date(with_tz(date4, "UTC"))) }) lubridate/tests/testthat/test-stamp.R0000644000176200001440000001555213236356705017475 0ustar liggesuserscontext("Stamp") test_that("stamp selects the correct format", { test_dates <- read.table(header = T, stringsAsFactors=F, textConnection(" date expected 'February 20th 1973' 'August 13th 2012' ## 'february 14, 2004' 'August 13, 2012' 'Sunday, May 1, 2000' 'Monday, Aug 13, 2012' 'Sunday, May 1, 2000' 'Monday, Aug 13, 2012' 'february 14, 04' 'August 13, 12' 'Feb 20th 73' 'Aug 13th 12' 'January 5 1999 at 7pm' 'August 13 2012 at 11AM' 'jan 3 2010' 'Aug 13 2012' 'Jan 1, 1999' 'Aug 13, 2012' 'jan 3 10' 'Aug 13 12' '01 3 2010' '08 13 2012' '1 3 10' '08 13 12' '1 13 89' '08 13 12' '5/27/1979' '08/13/2012' '12/31/99' '08/13/12' 'DOB:12/11/00' 'DOB:08/13/12' 'Thu, 1 July 2004 22:30:00' 'Mon, 13 August 2012 11:37:53' 'Thu, 1st of July 2004 at 22:30:00' 'Mon, 13st of August 2012 at 11:37:53' 'Thu, 1July 2004 at 22:30:00' 'Mon, 13August 2012 at 11:37:53' 'Thu, 1July2004 22:30:00' 'Mon, 13August2012 11:37:53' ## '21 Aug 2011, 11:15:34 pm' '13 Aug 2012, 11:37:53 AM' '1979-05-27 05:00:59' '2012-08-13 11:37:53' '1979-05-27' '2012-08-13' '3 jan 2000' '13 Aug 2012' '17 april 85' '13 August 12' '27/5/1979' '13/08/2012' '20 01 89' '13 08 12' '00/13/10' '12/13/08' '14 12 00' '13 08 12' ## '03:23:22 PM' '11:37:53 AM' '2001-12-31T04:05:06Z' '2012-08-13T11:37:53Z' ")) D <- as.POSIXct("2012-08-13 11:37:53", tz = "UTC") for (i in seq_along(test_dates$date)) { ## print(i) expect_equal(stamp(test_dates[[i, "date"]])(D), test_dates[[i, "expected"]]) } }) test_that(".format_offset works as expected", { df_winter <- data.frame( tz = c("America/Chicago", "UTC", "Europe/Paris"), Oo = c("-06", "+00", "+01"), Oz = c("-0600", "+0000", "+0100"), OO = c("-06:00", "+00:00", "+01:00"), stringsAsFactors = FALSE ) with(df_winter, for (i in 1:nrow(df_winter)) { expect_equal(.format_offset(ymd("2013-01-01", tz = tz[i]), "%Oo"), Oo[i]) expect_equal(.format_offset(ymd("2013-01-01", tz = tz[i]), "%Oz"), Oz[i]) expect_equal(.format_offset(ymd("2013-01-01", tz = tz[i]), "%OO"), OO[i]) }) df_summer <- data.frame( tz = c("America/Chicago", "UTC", "Europe/Paris"), Oo = c("-05", "+00", "+02"), Oz = c("-0500", "+0000", "+0200"), OO = c("-05:00", "+00:00", "+02:00"), stringsAsFactors = FALSE ) with(df_summer, for (i in 1:nrow(df_summer)) { expect_equal(.format_offset(ymd("2013-07-01", tz = tz[i]), "%Oo"), Oo[i]) expect_equal(.format_offset(ymd("2013-07-01", tz = tz[i]), "%Oz"), Oz[i]) expect_equal(.format_offset(ymd("2013-07-01", tz = tz[i]), "%OO"), OO[i]) }) ## half-hour timezone expect_warning(.format_offset(ymd("2013-07-01", tz = "Asia/Kolkata"), "%Oo")) expect_equal(suppressWarnings(.format_offset(ymd("2013-07-01", tz = "Asia/Kolkata"), "%Oo")), "+0530") expect_equal(.format_offset(ymd("2013-07-01", tz = "Asia/Kolkata"), "%Oz"), "+0530") expect_equal(.format_offset(ymd("2013-07-01", tz = "Asia/Kolkata"), "%OO"), "+05:30") }) test_that("stamp works with ISO-8601 formats", { stamp_Ou <- stamp("2013-01-01T06:00:00Z") stamp_Oo <- stamp("2013-01-01T00:00:00-06") stamp_Oz <- stamp("2013-01-01T00:00:00-0600") stamp_OO <- stamp("2013-01-01T00:00:00-06:00") tz <- c("America/Chicago", "UTC", "Europe/Paris") Ou <- c("2013-01-01T06:00:00Z", "2013-01-01T00:00:00Z", "2012-12-31T23:00:00Z") Oo <- c("2013-01-01T00:00:00-06", "2013-01-01T00:00:00+00", "2013-01-01T00:00:00+01") Oz <- c("2013-01-01T00:00:00-0600", "2013-01-01T00:00:00+0000", "2013-01-01T00:00:00+0100") OO <- c("2013-01-01T00:00:00-06:00", "2013-01-01T00:00:00+00:00", "2013-01-01T00:00:00+01:00") ## cbind(tz, Ou, Oo, Oz, OO) # if you want to see them for (i in seq_along(tz)) { expect_equal(stamp_Ou(ymd("2013-01-01", tz = tz[i])), Ou[i]) expect_equal(stamp_Oo(ymd("2013-01-01", tz = tz[i])), Oo[i]) expect_equal(stamp_Oz(ymd("2013-01-01", tz = tz[i])), Oz[i]) expect_equal(stamp_OO(ymd("2013-01-01", tz = tz[i])), OO[i]) } ## half-hour timezone expect_equal(suppressWarnings(stamp_Ou(ymd("2013-01-01", tz = "Asia/Kolkata"))), "2012-12-31T18:30:00Z") expect_warning(stamp_Oo(ymd("2013-01-01", tz = "Asia/Kolkata"))) expect_equal(suppressWarnings(stamp_Oo(ymd("2013-01-01", tz = "Asia/Kolkata"))), "2013-01-01T00:00:00+0530") expect_equal(stamp_Oz(ymd("2013-01-01", tz = "Asia/Kolkata")), "2013-01-01T00:00:00+0530") expect_equal(stamp_OO(ymd("2013-01-01", tz = "Asia/Kolkata")), "2013-01-01T00:00:00+05:30") ## vectorization expect_equal(stamp_OO(ymd(c("2013-01-01", "2010-01-01"), tz = "Asia/Kolkata")), c("2013-01-01T00:00:00+05:30", "2010-01-01T00:00:00+05:30")) ## format not at end of template (fails on windows 7, %z output format is ## completely screwed there) ## stamp_OO_strange <- stamp("2013-01-01T00:00:00-06:00 KK") ## expect_equal(stamp_OO_strange(ymd("2013-01-01", tz="Asia/Kolkata")), ## "2012-12-31T18:30:00+0000 KK") }) test_that("stamp recognizes correctly B orders", { formater <- stamp("Sunday, November 30, 23:15", "ABdHM") x <- ymd_hm(c("2017-01-20 15:15", "2017-02-11 10:10")) expect_equal(formater(x), c("Friday, January 20, 15:15", "Saturday, February 11, 10:10")) }) ## ## Don't delete this. We need it for interactive testing ## y <- c('February 20th 1973', ## "february 14, 2004", ## "Sunday, May 1, 2000", ## "Sunday, May012000", ## "february 14, 04", ## 'Feb 20th 73', ## "January 5 1999 at 7pm", ## "jan 3 2010", ## "Jan 1, 1999", ## "jan 3 10", ## "01 3 2010", ## "1 3 10", ## '1 13 89', ## "5/27/1979", ## "12/31/99", ## "DOB:12/11/00", ## 'Thu, 1 July 2004 22:30:00', ## 'Thu, 1st of July 2004 at 22:30:00', ## 'Thu, 1July 2004 at 22:30:00', ## 'Thu, 1July2004 22:30:00', ## "21 Aug 2011, 11:15:34 pm", ## "1979-05-27 05:00:59", ## "1979-05-27", ## "3 jan 2000", ## "17 april 85", ## "27/5/1979", ## '20 01 89', ## '00/13/10', ## "14 12 00", ## "03:23:22 pm") ## cbind(y, unlist(lapply(y, function(x) stamp(x)(D)))) lubridate/tests/testthat/test-timespans.R0000644000176200001440000001233313201152061020323 0ustar liggesuserscontext("Timespans") test_that("is.timespan works as expected", { expect_that(is.timespan(234), is_false()) expect_that(is.timespan(as.POSIXct("2008-08-03 13:01:59", tz = "UTC")), is_false()) expect_that(is.timespan(as.POSIXlt("2008-08-03 13:01:59", tz = "UTC")), is_false()) expect_that(is.timespan(Sys.Date()), is_false()) expect_that(is.timespan(minutes(1)), is_true()) expect_that(is.timespan(dminutes(1)), is_true()) expect_that(is.timespan(interval( as.POSIXct("2008-08-03 13:01:59", tz = "UTC"), as.POSIXct("2009-08-03 13:01:59", tz = "UTC"))), is_true()) }) test_that("is.timespan handles vectors", { expect_that(is.timespan(minutes(1:3)), is_true()) }) test_that("time_length works as expected", { expect_that(time_length(period(1, "day")), # period equals(86400)) expect_that(time_length(ymd("2014-12-15") - ymd("2014-11-30"), "day"), # difftime equals(15)) expect_that(time_length(ymd("2014-12-15") - ymd("2014-11-30"), "week"), equals(15/7)) expect_that(time_length(duration(3, "months"), "month"), # duration equals(3)) expect_that(time_length(interval(ymd("2014-11-30"), ymd("2014-12-15")), "weeks"), # interval equals(15/7)) expect_that(time_length(interval(ymd("1900-01-01"), ymd("1999-12-31")), "years"), is_less_than(100)) expect_that(time_length(as.duration(interval(ymd("1900-01-01"), ymd("1999-12-31"))), "years"), is_more_than(100)) expect_that(-time_length(interval(ymd("1900-01-01"), ymd("2000-01-01")), "days"), equals(time_length(int_flip(interval(ymd("1900-01-01"), ymd("2000-01-01"))), "days"))) }) test_that("time_length works with missing intervals", { expect_equal(time_length(interval(NA, ymd("2016-01-01")), unit = "year"), NA_real_) }) test_that("time_length works with birth date 29 Feb ", { expect_that(round(time_length(interval(ymd("1992-02-29"), ymd("1999-02-28")), "years"), 4), equals(6.9973)) expect_that(round(time_length(interval(ymd("1992-02-29"), ymd("1999-03-31")), "years"), 4), equals(7.0822)) expect_that(time_length(interval(ymd("1992-02-29"), ymd("1999-03-01")), "years"), equals(7)) expect_that(round(time_length(interval(ymd("1992-02-29"), ymd("2000-03-01")), "years"), 4), equals(8.0027)) expect_that(time_length(interval(ymd("1992-02-29"), ymd("2000-02-29")), "years"), equals(8)) expect_that(time_length(interval(ymd_hms("1992-02-29 12:00:00"), ymd_hms("1999-03-01 05:00:00")), "years"), is_more_than(7)) }) test_that("time_length works with negative interals", { expect_that(-time_length(interval(ymd("1992-02-28"), ymd("2000-01-01")), "days"), equals(time_length(int_flip(interval(ymd("1992-02-28"), ymd("2000-01-01"))), "days"))) expect_that(-time_length(interval(ymd("1992-02-28"), ymd("2000-03-01")), "days"), equals(time_length(int_flip(interval(ymd("1992-02-28"), ymd("2000-03-01"))), "days"))) ## If both ends include leap years Febs, the lenths are not identical int <- interval(ymd("1992-02-28"), ymd("2000-03-01")) expect_equal(-time_length(int, "years"), time_length(int_flip(int), "years")) ## or if both ends don't include leap years Febs, the lenths are identical int <- interval(ymd("1994-02-28"), ymd("2002-03-01")) expect_equal(-time_length(int, "years"), time_length(int_flip(int), "years")) ## ... otherwise not int <- interval(ymd("1992-02-28"), ymd("2002-01-01")) expect_gt(-time_length(int, "years"), time_length(int_flip(int), "years")) }) test_that("time_length handles vectors", { expect_that(time_length(days(1:3), unit = "days"), equals(1:3)) expect_that(time_length(as.interval(days(1:3), start = today()), unit = "days"), equals(1:3)) expect_that(time_length(as.interval(days(c(1:3, NA)), start = today()), unit = "days"), equals(c(1:3, NA))) ints <- new("Interval" , .Data = c(6363040, 1646253613, 159312603, -510371200, -381983229, 1369742727, -190254638, -1118394043, -2091814107) , start = structure(c(64156663, 326788049, 462064351, 909110414, 778538359, 395846311, 1415640365, 1697694335, 2193040469), class = c("POSIXct", "POSIXt"), tzone = "UTC") , tzone = "UTC") expect_equal(round(time_length(ints, "years"), 5), c(0.20122, 52.16674, 5.04903, -16.17281, -12.10439, 43.40412, -6.03011, -35.44092, -66.28715)) expect_equal(round(time_length(ints[ints > 0], "years"), 5), c(0.20122, 52.16674, 5.04903, 43.40412)) expect_equal(round(time_length(ints[ints < 0], "years"), 5), c(-16.17281, -12.10439, -6.03011, -35.44092, -66.28715)) expect_equal(round(time_length(ints, "month"), 5), c(2.4402, 625.99552, 60.57729, -194.06691, -145.2291, 520.81679, -72.35552, -425.27918, -795.43557)) }) test_that("time_length handles 0 length intervals", { date <- ymd_hms("2014-12-30 20:35:13") int <- interval(c(date, date), c(date, date)) expect_equal(time_length(int), c(0, 0)) expect_equal(time_length(int, "years"), c(0, 0)) expect_equal(time_length(int, "months"), c(0, 0)) }) lubridate/tests/testthat/test-rollback.R0000644000176200001440000000132613201152061020111 0ustar liggesuserscontext("Rollback") test_that("rollback returns correct results", { expect_equal(rollback(ymd_hms("2010-03-03 12:44:22")), ymd_hms("2010-02-28 12:44:22")) expect_equal(rollback(ymd_hms("2010-03-03 12:44:22"), preserve_hms = FALSE), ymd_hms("2010-02-28 00:00:00")) expect_equal(rollback(ymd_hms("2010-03-03 12:44:22"), roll_to_first = TRUE), ymd_hms("2010-03-01 12:44:22")) expect_equal(rollback(ymd_hms("2010-03-03 12:44:22"), roll_to_first = TRUE, preserve_hms = FALSE), ymd_hms("2010-03-01 00:00:00")) }) test_that("rollback works with missing numbers", { expect_equal(ymd(c("20150131", NA)) %m+% months(1), ymd(c("201502-28", NA))) }) lubridate/tests/testthat/test-update.R0000644000176200001440000005033613236565710017630 0ustar liggesuserscontext("Updating dates") test_that("update.Date returns a date object", { date <- as.Date("05/05/2010", "%m/%d/%Y") expect_that(update(date, days = 1), is_a("Date")) expect_that(update(date, yday = 1), is_a("Date")) expect_that(update(date, mday = 1), is_a("Date")) expect_that(update(date, wday = 1), is_a("Date")) expect_that(update(date, month = 1), is_a("Date")) expect_that(update(date, year = 2001), is_a("Date")) expect_that(update(date, tz = "UTC"), is_a("Date")) }) test_that("update.Date returns a posix object if time is manipulated", { date <- as.Date("05/05/2010", "%m/%d/%Y") expect_that(update(date, seconds = 1), is_a("POSIXt")) expect_that(update(date, minutes = 1), is_a("POSIXt")) expect_that(update(date, hours = 1), is_a("POSIXt")) }) test_that("update.POSIXlt returns a POSIXlt object", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") expect_that(update(poslt, seconds = 1), is_a("POSIXlt")) expect_that(update(poslt, minutes = 1), is_a("POSIXlt")) expect_that(update(poslt, hours = 1), is_a("POSIXlt")) expect_that(update(poslt, days = 1), is_a("POSIXlt")) expect_that(update(poslt, yday = 1), is_a("POSIXlt")) expect_that(update(poslt, mday = 1), is_a("POSIXlt")) expect_that(update(poslt, wday = 1), is_a("POSIXlt")) expect_that(update(poslt, month = 1), is_a("POSIXlt")) expect_that(update(poslt, year = 2001), is_a("POSIXlt")) expect_that(update(poslt, tz = "UTC"), is_a("POSIXlt")) }) test_that("update.POSIXct returns a POSIXct object", { posct <- as.POSIXct("2010-02-03 13:45:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") expect_that(update(posct, seconds = 1), is_a("POSIXct")) expect_that(update(posct, minutes = 1), is_a("POSIXct")) expect_that(update(posct, hours = 1), is_a("POSIXct")) expect_that(update(posct, days = 1), is_a("POSIXct")) expect_that(update(posct, yday = 1), is_a("POSIXct")) expect_that(update(posct, mday = 1), is_a("POSIXct")) expect_that(update(posct, wday = 1), is_a("POSIXct")) expect_that(update(posct, month = 1), is_a("POSIXct")) expect_that(update(posct, year = 2001), is_a("POSIXct")) expect_that(update(posct, tz = "UTC"), is_a("POSIXct")) }) test_that("update.Date performs simple operation as expected", { date <- as.Date("05/05/2010", "%m/%d/%Y") expect_that(second(update(date, seconds = 1)), equals(1)) expect_that(minute(update(date, minutes = 1)), equals(1)) expect_that(hour(update(date, hours = 1)), equals(1)) expect_that(mday(update(date, mday = 1)), equals(1)) expect_that(wday(update(date, mday = 1)), equals(7)) expect_that(yday(update(date, mday = 1)), equals(121)) expect_that(yday(update(date, yday = 1)), equals(1)) expect_that(mday(update(date, yday = 1)), equals(1)) expect_that(wday(update(date, yday = 1)), equals(6)) expect_that(wday(update(date, wday = 1)), equals(1)) expect_that(yday(update(date, wday = 1)), equals(122)) expect_that(mday(update(date, wday = 1)), equals(2)) expect_that(month(update(date, months = 1)), equals(1)) expect_that(year(update(date, years = 2000)), equals(2000)) expect_match(tz(update(date, tz = "UTC")), "UTC") }) test_that("update.POSIXt performs simple operation as expected", { poslt <- as.POSIXlt("2010-02-03 13:45:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct("2010-02-03 13:45:59", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") expect_that(second(update(poslt, seconds = 1)), equals(1)) expect_that(minute(update(poslt, minutes = 1)), equals(1)) expect_that(hour(update(poslt, hours = 1)), equals(1)) expect_that(mday(update(poslt, mday = 1)), equals(1)) expect_that(wday(update(poslt, mday = 1)), equals(2)) expect_that(yday(update(poslt, mday = 1)), equals(32)) expect_that(yday(update(poslt, yday = 1)), equals(1)) expect_that(mday(update(poslt, yday = 1)), equals(1)) expect_that(wday(update(poslt, yday = 1)), equals(6)) expect_that(wday(update(poslt, wday = 1)), equals(1)) expect_that(yday(update(poslt, wday = 1)), equals(31)) expect_that(mday(update(poslt, wday = 1)), equals(31)) expect_that(month(update(poslt, months = 1)), equals(1)) expect_that(year(update(poslt, years = 2000)), equals(2000)) expect_match(tz(update(poslt, tz = "UTC")), "UTC") expect_that(second(update(posct, seconds = 1)), equals(1)) expect_that(minute(update(posct, minutes = 1)), equals(1)) expect_that(hour(update(posct, hours = 1)), equals(1)) expect_that(mday(update(posct, mday = 1)), equals(1)) expect_that(wday(update(posct, mday = 1)), equals(2)) expect_that(yday(update(posct, mday = 1)), equals(32)) expect_that(yday(update(posct, yday = 1)), equals(1)) expect_that(mday(update(posct, yday = 1)), equals(1)) expect_that(wday(update(posct, yday = 1)), equals(6)) expect_that(wday(update(posct, wday = 1)), equals(1)) expect_that(yday(update(posct, wday = 1)), equals(31)) expect_that(mday(update(posct, wday = 1)), equals(31)) expect_that(month(update(posct, months = 1)), equals(1)) expect_that(year(update(posct, years = 2000)), equals(2000)) expect_match(tz(update(posct, tz = "UTC")), "UTC") }) test_that("update.POSIXt works on wdays", { date <- ymd("2017-05-07") ## sunday ct <- as.POSIXct("2010-02-03 13:45:59", tz = "America/New_York", format = "%Y-%m-%d %H:%M:%S") ## Wednesday expect_equal(wday(update(ct, wday = 1)), 1) expect_equal(wday(update(ct, wday = 2)), 2) expect_equal(wday(update(ct, wday = 5)), 5) expect_equal(wday(update(ct, wday = 7)), 7) expect_equal(wday(update(date, wday = 1)), 1) expect_equal(wday(update(date, wday = 2)), 2) expect_equal(wday(update(date, wday = 5)), 5) expect_equal(wday(update(date, wday = 7)), 7) ws <- 1 expect_equal(wday(update(ct, wday = 1, week_start = ws)), 2) expect_equal(wday(update(ct, wday = 2, week_start = ws)), 3) expect_equal(wday(update(ct, wday = 5, week_start = ws)), 6) expect_equal(wday(update(ct, wday = 7, week_start = ws)), 1) expect_equal(wday(update(date, wday = 1, week_start = ws)), 2) expect_equal(wday(update(date, wday = 2, week_start = ws)), 3) expect_equal(wday(update(date, wday = 5, week_start = ws)), 6) expect_equal(wday(update(date, wday = 7, week_start = ws)), 1) ws <- 1 expect_equal(wday(update(ct, wday = 1, week_start = ws), week_start = ws), 1) expect_equal(wday(update(ct, wday = 2, week_start = ws), week_start = ws), 2) expect_equal(wday(update(ct, wday = 5, week_start = ws), week_start = ws), 5) expect_equal(wday(update(ct, wday = 7, week_start = ws), week_start = ws), 7) expect_equal(wday(update(date, wday = 1, week_start = ws), week_start = ws), 1) expect_equal(wday(update(date, wday = 2, week_start = ws), week_start = ws), 2) expect_equal(wday(update(date, wday = 5, week_start = ws), week_start = ws), 5) expect_equal(wday(update(date, wday = 7, week_start = ws), week_start = ws), 7) ws <- 3 expect_equal(wday(update(ct, wday = 1, week_start = ws), week_start = ws), 1) expect_equal(wday(update(ct, wday = 2, week_start = ws), week_start = ws), 2) expect_equal(wday(update(ct, wday = 5, week_start = ws), week_start = ws), 5) expect_equal(wday(update(ct, wday = 7, week_start = ws), week_start = ws), 7) expect_equal(wday(update(date, wday = 1, week_start = ws), week_start = ws), 1) expect_equal(wday(update(date, wday = 2, week_start = ws), week_start = ws), 2) expect_equal(wday(update(date, wday = 5, week_start = ws), week_start = ws), 5) expect_equal(wday(update(date, wday = 7, week_start = ws), week_start = ws), 7) }) test_that("updates on ydays works correctly with leap years", { expect_equal(update(ymd("15-02-03", tz = "UTC"), year = 2000, yday = 1), ymd("2000-01-01", tz = "UTC")) expect_equal(update(ymd("15-02-03", tz = "UTC"), year = 2015, yday = 1), ymd("2015-01-01", tz = "UTC")) expect_equal(update(ymd("15-02-03", tz = "UTC"), year = 2016, yday = 10), ymd("2016-01-10", tz = "UTC")) expect_equal(update(ymd("15-02-03", tz = "America/New_York"), year = 2000, yday = 1), ymd("2000-01-01", tz = "America/New_York")) expect_equal(update(ymd("15-02-03", tz = "America/New_York"), year = 2015, yday = 1), ymd("2015-01-01", tz = "America/New_York")) expect_equal(update(ymd("15-02-03", tz = "America/New_York"), year = 2016, yday = 10), ymd("2016-01-10", tz = "America/New_York")) expect_equal(update(ymd(c("2016-02-29", "2016-03-01")), yday = 1), ymd(c("2016-01-01", "2016-01-01"))) expect_equal(update(ymd(c("2016-02-29", "2016-03-01"), tz = "America/New_York"), yday = 1), ymd(c("2016-01-01", "2016-01-01"), tz = "America/New_York")) expect_equal(update(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30")), yday = 1), ymd_hms(c("2016-01-01 1:2:3", "2016-01-01 10:20:30"))) expect_equal(update(ymd_hms(c("2016-02-29 1:2:3", "2016-03-01 10:20:30"), tz = "America/New_York"), yday = 1), ymd_hms(c("2016-01-01 1:2:3", "2016-01-01 10:20:30"), tz = "America/New_York")) }) test_that("update performs roll overs correctly for Date objects", { date <- as.Date("05/05/2010", "%m/%d/%Y") expect_that(second(update(date, seconds = 61)), equals(1)) expect_that(minute(update(date, seconds = 61)), equals(1)) expect_that(minute(update(date, minutes = 61)), equals(1)) expect_that(hour(update(date, minutes = 61)), equals(1)) expect_that(hour(update(date, hours = 25)), equals(1)) expect_that(mday(update(date, hours = 25)), equals(6)) expect_that(yday(update(date, hours = 25)), equals(126)) expect_that(wday(update(date, hours = 25)), equals(5)) expect_that(mday(update(date, mday = 32)), equals(1)) expect_that(month(update(date, mday = 32)), equals(6)) expect_that(wday(update(date, wday = 31)), equals(3)) expect_that(month(update(date, wday = 31)), equals(6)) expect_that(yday(update(date, yday = 366)), equals(1)) expect_that(month(update(date, yday = 366)), equals(1)) expect_that(month(update(date, month = 13)), equals(1)) expect_that(year(update(date, month = 13)), equals(2011)) expect_match(tz(update(date, month = 13)), "UTC") }) test_that("update performs roll overs correctly for POSIXlt objects", { poslt <- as.POSIXlt("2010-05-05 00:00:00", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") expect_that(second(update(poslt, seconds = 61)), equals(1)) expect_that(minute(update(poslt, seconds = 61)), equals(1)) expect_that(minute(update(poslt, minutes = 61)), equals(1)) expect_that(hour(update(poslt, minutes = 61)), equals(1)) expect_that(hour(update(poslt, hours = 25)), equals(1)) expect_that(mday(update(poslt, hours = 25)), equals(6)) expect_that(yday(update(poslt, hours = 25)), equals(126)) expect_that(wday(update(poslt, hours = 25)), equals(5)) expect_that(mday(update(poslt, mday = 32)), equals(1)) expect_that(month(update(poslt, mday = 32)), equals(6)) expect_that(wday(update(poslt, wday = 31)), equals(3)) expect_that(month(update(poslt, wday = 31)), equals(6)) expect_that(yday(update(poslt, yday = 366)), equals(1)) expect_that(month(update(poslt, yday = 366)), equals(1)) expect_that(month(update(poslt, month = 13)), equals(1)) expect_that(year(update(poslt, month = 13)), equals(2011)) expect_match(tz(update(poslt, month = 13)), "GMT") }) test_that("update performs roll overs correctly for POSIXct objects", { posct <- as.POSIXct("2010-05-05 00:00:00", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") expect_that(second(update(posct, seconds = 61)), equals(1)) expect_that(minute(update(posct, seconds = 61)), equals(1)) expect_that(minute(update(posct, minutes = 61)), equals(1)) expect_that(hour(update(posct, minutes = 61)), equals(1)) expect_that(hour(update(posct, hours = 25)), equals(1)) expect_that(mday(update(posct, hours = 25)), equals(6)) expect_that(yday(update(posct, hours = 25)), equals(126)) expect_that(wday(update(posct, hours = 25)), equals(5)) expect_that(mday(update(posct, mday = 32)), equals(1)) expect_that(month(update(posct, mday = 32)), equals(6)) expect_that(wday(update(posct, wday = 31)), equals(3)) expect_that(month(update(posct, wday = 31)), equals(6)) expect_that(yday(update(posct, yday = 366)), equals(1)) expect_that(month(update(posct, yday = 366)), equals(1)) expect_that(month(update(posct, month = 13)), equals(1)) expect_that(year(update(posct, month = 13)), equals(2011)) expect_match(tz(update(posct, month = 13)), "GMT") }) test_that("update performs consecutive roll overs correctly for Date objects regardless of order", { date <- update(as.Date("11/01/2010", "%m/%d/%Y"), months = 13, days = 32, hours = 25, minutes = 61, seconds = 61) expect_that(second(date), equals(1)) expect_that(minute(date), equals(2)) expect_that(hour(date), equals(2)) expect_that(mday(date), equals(2)) expect_that(wday(date), equals(4)) expect_that(yday(date), equals(33)) expect_that(month(date), equals(2)) expect_that(year(date), equals(2011)) expect_match(tz(date), "UTC") date2 <- update(as.Date("11/01/2010", "%m/%d/%Y"), seconds = 61, minutes = 61, hours = 25, days = 32, months = 13) expect_that(second(date2), equals(1)) expect_that(minute(date2), equals(2)) expect_that(hour(date2), equals(2)) expect_that(mday(date2), equals(2)) expect_that(wday(date2), equals(4)) expect_that(yday(date2), equals(33)) expect_that(month(date2), equals(2)) expect_that(year(date2), equals(2011)) expect_match(tz(date2), "UTC") }) test_that("update performs consecutive roll overs correctly for POSIXlt objects", { posl <- as.POSIXlt("2010-11-01 00:00:00", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") poslt <- update(posl, months = 13, days = 32, hours = 25, minutes = 61, seconds = 61) expect_that(second(poslt), equals(1)) expect_that(minute(poslt), equals(2)) expect_that(hour(poslt), equals(2)) expect_that(mday(poslt), equals(2)) expect_that(wday(poslt), equals(4)) expect_that(yday(poslt), equals(33)) expect_that(month(poslt), equals(2)) expect_that(year(poslt), equals(2011)) expect_match(tz(poslt), "GMT") poslt2 <- update(posl, seconds = 61, minutes = 61, hours = 25, days = 32, months = 13) expect_that(second(poslt2), equals(1)) expect_that(minute(poslt2), equals(2)) expect_that(hour(poslt2), equals(2)) expect_that(mday(poslt2), equals(2)) expect_that(wday(poslt2), equals(4)) expect_that(yday(poslt2), equals(33)) expect_that(month(poslt2), equals(2)) expect_that(year(poslt2), equals(2011)) expect_match(tz(poslt2), "GMT") }) test_that("update performs consecutive roll overs correctly for POSIXct objects", { posc <- as.POSIXct("2010-11-01 00:00:00", tz = "GMT", format = "%Y-%m-%d %H:%M:%S") posct <- update(posc, months = 13, days = 32, hours = 25, minutes = 61, seconds = 61) expect_that(second(posct), equals(1)) expect_that(minute(posct), equals(2)) expect_that(hour(posct), equals(2)) expect_that(mday(posct), equals(2)) expect_that(wday(posct), equals(4)) expect_that(yday(posct), equals(33)) expect_that(month(posct), equals(2)) expect_that(year(posct), equals(2011)) expect_match(tz(posct), "GMT") posct2 <- update(posc, seconds = 61, minutes = 61, hours = 25, days = 32, months = 13) expect_that(second(posct2), equals(1)) expect_that(minute(posct2), equals(2)) expect_that(hour(posct2), equals(2)) expect_that(mday(posct2), equals(2)) expect_that(wday(posct2), equals(4)) expect_that(yday(posct2), equals(33)) expect_that(month(posct2), equals(2)) expect_that(year(posct2), equals(2011)) expect_match(tz(posct2), "GMT") }) test_that("update returns NA for date-times in the spring dst gap", { poslt <- as.POSIXlt("2010-03-14 01:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") expect_that(is.na(update(poslt, seconds = 65)), is_true()) expect_that(is.na(update(poslt, minutes = 65)), is_true()) expect_that(is.na(update(poslt, hours = 2)), is_true()) poslt <- as.POSIXlt("2010-03-13 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") expect_that(is.na(update(poslt, mday = 14)), is_true()) expect_that(is.na(update(poslt, wday = 8)), is_true()) expect_that(is.na(update(poslt, yday = 73)), is_true()) poslt <- as.POSIXlt("2010-02-14 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") expect_that(is.na(update(poslt, months = 3)), is_true()) poslt <- as.POSIXlt("2009-03-14 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") poslt <- force_tz(poslt, tz = "America/New_York") expect_that(is.na(update(poslt, years = 2010)), is_true()) poslt <- as.POSIXlt("2010-03-14 02:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") expect_that(is.na(update(poslt, tz = "America/New_York")), is_true()) }) test_that("update handles vectors of dates", { poslt <- as.POSIXlt(c("2010-02-14 01:59:59", "2010-02-15 01:59:59", "2010-02-16 01:59:59"), tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(second(update(poslt, seconds = 1)), equals(c(1, 1, 1))) expect_that(second(update(posct, seconds = 1)), equals(c(1, 1, 1))) expect_that(day(update(date, days = 1)), equals(c(1, 1, 1))) }) test_that("update handles vectors of dates and conformable vector of inputs", { poslt <- as.POSIXlt(c("2010-02-14 01:59:59", "2010-02-15 01:59:59", "2010-02-16 01:59:59"), tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(second(update(poslt, seconds = c(1, 2, 3))), equals(c(1, 2, 3))) expect_that(second(update(posct, seconds = c(1, 2, 3))), equals(c(1, 2, 3))) expect_that(day(update(date, days = c(1, 2, 3))), equals(c(1, 2, 3))) }) test_that("update handles single vector of inputs", { poslt <- as.POSIXlt("2010-03-14 01:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(second(update(poslt, seconds = c(1, 2, 3))), equals(c(1, 2, 3))) expect_that(second(update(posct, seconds = c(1, 2, 3))), equals(c(1, 2, 3))) expect_that(day(update(date, days = c(1, 2, 3))), equals(c(1, 2, 3))) }) test_that("update handles conformable vectors of inputs", { poslt <- as.POSIXlt("2010-03-10 01:59:59", tz = "UTC", format = "%Y-%m-%d %H:%M:%S") posct <- as.POSIXct(poslt) date <- as.Date(poslt) expect_that(second(update(poslt, seconds = c(1, 2), minutes = c(1, 2, 3, 4))), equals(c(1, 2, 1, 2))) expect_that(second(update(posct, seconds = c(1, 2), minutes = c(1, 2, 3, 4))), equals(c(1, 2, 1, 2))) expect_that(day(update(date, days = c(1, 2), months = c(1, 2, 3, 4))), equals(c(1, 2, 1, 2))) }) test_that("update.POSIXct returns input of length zero when given input of length zero", { x <- structure(vector(mode = "numeric"), class = c("POSIXct", "POSIXt")) expect_equal(update(x, days = 1), x) }) test_that("update.POSIXlt returns input of length zero when given input of length zero", { x <- as.POSIXlt(structure(vector(mode = "numeric"), class = c("POSIXct", "POSIXt"))) expect_equal(update(x, days = 1), x) }) test_that("update correctly handles 60 seconds on 59 minute (bug #313)", { expect_equal(ymd_hms("2015-01-01 00:59:00") + seconds(60), ymd_hms("2015-01-01 01:00:00")) expect_equal(ymd_hms("2015-01-01 01:59:00") + seconds(60), ymd_hms("2015-01-01 02:00:00")) expect_equal(ymd_hms("2015-01-01 23:59:00") + seconds(60), ymd_hms("2015-01-02 00:00:00")) expect_equal(ymd_hms("2015-01-01 00:59:05") + seconds(55), ymd_hms("2015-01-01 01:00:00")) expect_equal(ymd_hms("2015-01-01 00:59:59") + seconds(1), ymd_hms("2015-01-01 01:00:00")) }) test_that("Updateing on seconds doesn't affect hours", { ## https://github.com/tidyverse/lubridate/issues/619 tt <- Sys.time() tt2 <- tt second(tt2) <- 5 expect_equal(hour(tt), hour(tt2)) }) ## ## bug #319 ## x <- structure(list(sec = 0, min = 0, hour = 0, mday = -212, mon = 7L, ## year = 108L, wday = NA_integer_, yday = NA_integer_, isdst = 0L, ## zone = "EST", gmtoff = -18000L), ## .Names = c("sec", "min", ## "hour", "mday", "mon", "year", "wday", "yday", "isdst", "zone", ## "gmtoff"), ## tzone = c("America/New_York", "EST", "EDT"), ## class = c("POSIXlt", "POSIXt")) ## update(x, year = year(x) + 1) lubridate/tests/testthat/test-pretty.R0000644000176200001440000000174613236356705017700 0ustar liggesuserscontext("Pretty formatting of dates") test_that("pretty_dates works for years", { ## skip anything that uses setenv(TZ) on CRAN for now skip_on_cran() ## https://github.com/hadley/lubridate/issues/227 expect_equal(pretty_dates(c(as.Date("1993-12-05"), as.Date("2007-12-01")), 7), ymd(c("1993-01-01 UTC", "1995-01-01 UTC", "1997-01-01 UTC", "1999-01-01 UTC", "2001-01-01 UTC", "2003-01-01 UTC", "2005-01-01 UTC", "2007-01-01 UTC"), tz = "UTC")) ## https://github.com/hadley/lubridate/issues/248 expect_equal( pretty_dates(ymd_hms("2014-02-05 22:45:46 GMT", "2014-03-03 14:28:20"), 10), ymd(c("2014-02-05 UTC", "2014-02-07 UTC", "2014-02-09 UTC", "2014-02-11 UTC", "2014-02-13 UTC", "2014-02-15 UTC", "2014-02-17 UTC", "2014-02-19 UTC", "2014-02-21 UTC", "2014-02-23 UTC", "2014-02-25 UTC", "2014-02-27 UTC", "2014-03-01 UTC", "2014-03-03 UTC"), tz = "UTC")) }) lubridate/tests/testthat/test-intervals.R0000644000176200001440000006530713263125772020361 0ustar liggesuserscontext("Intervals") test_that("is.interval works as expected", { expect_that(is.interval(234), is_false()) expect_that(is.interval(as.POSIXct("2008-08-03 13:01:59", tz = "UTC")), is_false()) expect_that(is.interval(as.POSIXlt("2008-08-03 13:01:59", tz = "UTC")), is_false()) expect_that(is.interval(Sys.Date()), is_false()) expect_that(is.interval(minutes(1)), is_false()) expect_that(is.interval(dminutes(1)), is_false()) expect_that(is.interval(interval( as.POSIXct("2008-08-03 13:01:59", tz = "UTC"), as.POSIXct("2009-08-03 13:01:59", tz = "UTC"))), is_true()) }) test_that("Parsing of iso 8601 intervals works", { expect_equal(interval("2007-03-01T13:00:00Z/2008-05-11T15:30:00Z"), interval("2007-03-01T13:00:00Z", "2008-05-11T15:30:00Z")) expect_equal(interval("2007-03-01T13:00:00Z/P1Y2M10DT2H30M"), interval("2007-03-01T13:00:00Z", ymd_hms("2007-03-01T13:00:00Z") + period("P1Y2M10DT2H30M"))) expect_equal(interval("P1Y2M10DT2H30M/2008-05-11T15:30:00Z"), interval(ymd_hms("2008-05-11T15:30:00Z") - period("P1Y2M10DT2H30M"), "2008-05-11T15:30:00Z")) expect_equal(interval(c("P1Y2M10DT2H30M/2008-05-11T15:30:00Z", "P2H30M/2008-05-11T15:30:00Z")), interval(ymd_hms("2008-05-11T15:30:00Z") - period(c("P1Y2M10DT2H30M", "P2H30M")), "2008-05-11T15:30:00Z")) expect_equal(interval(c("P1Y2M10DT2H30M/2008-05-11T15:30:00Z", "2001-05-11T15:30:00Z/P2H30M")), interval(c(ymd_hms("2008-05-11T15:30:00Z") - period("P1Y2M10DT2H30M"), ymd_hms("2001-05-11T15:30:00Z")), c(ymd_hms("2008-05-11T15:30:00Z"), ymd_hms("2001-05-11T15:30:00Z") + period("P2H30M")))) }) test_that("is.interval handles vectors", { expect_that(is.interval(interval( as.POSIXct(c("2008-08-03 13:01:59", "2009-08-03 13:01:59"), tz = "UTC"), as.POSIXct("2010-08-03 13:01:59", tz = "UTC"))), is_true()) }) test_that("interval works as expected", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") int <- interval(time1, time2) num <- as.numeric(time2) - as.numeric(time1) expect_equal(int@.Data, num) expect_equal(int@start, time1) expect_is(int, "Interval") }) test_that("interval handles vector input", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") time3 <- as.POSIXct("2009-08-04 13:01:59", tz = "UTC") int <- interval(c(time1, time2), time3) num <- as.numeric(time3) - as.numeric(c(time1, time2)) expect_equal(int@.Data, num) expect_equal(int@start, c(time1, time2)) expect_is(int, "Interval") int2 <- interval(time1, c(time3, time2)) num2 <- as.numeric(c(time3, time2)) - as.numeric(time1) starts <- structure(c(time1, time1), "tzone" = "UTC") expect_equal(int2@.Data, num2) expect_equal(int2@start, starts) expect_is(int2, "Interval") }) test_that("format.Interval works as expected", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") int <- interval(time1, time2) expect_match(format(int), "2008-08-03 13:01:59 UTC--2009-08-03 13:01:59 UTC") }) test_that("interval handles character inputs", { t1 <- c("2007-01-01") t2 <- c("2007-08-01") expect_equal(interval(t1, t2), new("Interval", 18316800, start = as.POSIXct("2007-01-01", tz = "UTC"), tzone = "UTC")) t1 <- c("2007-01-01") t2 <- c("2007-08-01 00:01:02") expect_equal(interval(t1, t2), new("Interval", 18316862, start = as.POSIXct("2007-01-01", tz = "UTC"), tzone = "UTC")) }) test_that("interval handles POSIXlt inputs", { skip_on_cran() oldtz <- Sys.getenv("TZ") Sys.setenv(TZ = "America/Los_Angeles") on.exit(if (oldtz == "") Sys.unsetenv("TZ") else Sys.setenv(TZ = oldtz)) t1 <- as.POSIXlt("2007-01-01") t2 <- as.POSIXlt("2007-08-01") expect_equal(unclass(interval(t1, t2)), unclass(new("Interval", 18313200, start = as.POSIXct("2007-01-01"), tzone = "America/Los_Angeles"))) t1 <- as.POSIXlt("2007-01-01") t2 <- as.POSIXlt("2007-08-01 00:01:02") expect_equal(unclass(interval(t1, t2)), unclass(new("Interval", 18313262, start = as.POSIXct("2007-01-01"), tzone = "America/Los_Angeles"))) }) test_that("as.interval works as expected", { a <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") pint <- interval(a, a + days(1)) dint <- interval(a, a + ddays(1)) expect_equal(pint, as.interval(days(1), a)) expect_equal(dint, as.interval(ddays(1), a)) }) test_that("as.interval handles vector input", { a <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") b <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") pint <- interval(a, a + days(1:2)) dint <- interval(a, a + ddays(1:2)) pint1 <- interval(c(a, b), c(a, b) + days(1:2)) dint1 <- interval(c(a, b), c(a, b) + ddays(1:2)) pint2 <- interval(c(a, b), c(a, b) + days(1)) dint2 <- interval(c(a, b), c(a, b) + ddays(1)) expect_equal(pint, as.interval(days(1:2), a)) expect_equal(dint, as.interval(ddays(1:2), a)) expect_equal(pint1, as.interval(days(1:2), c(a, b))) expect_equal(dint1, as.interval(days(1:2), c(a, b))) expect_equal(pint2, as.interval(days(1), c(a, b))) expect_equal(dint2, as.interval(days(1), c(a, b))) }) test_that("[<- can subset intervals", { ints <- data.frame(spans = c(interval(ymd(20090201), ymd(20090101)), interval(ymd(20090201), ymd(20090101)))) my_int <- interval(ymd(18800101), ymd(18810101)) ints[1, 1] <- 31536000 ints[2, 1] <- my_int int2 <- interval(ymd(20090201), ymd(20100201)) expect_equal(ints[1, 1], int2) expect_equal(ints[2, 1], my_int) }) test_that("format.Interval correctly displays intervals of length 0", { int <- interval(ymd(18800101), ymd(18810101)) expect_output(print(int[FALSE]), "Interval\\(0)") }) test_that("interval handles correctly time zones of Date objects", { expect_equal(interval(as.Date("2011-01-01"), as.Date("2013-01-01")), interval(ymd("2011-01-01"), ymd("2013-01-01"))) }) test_that("summary.Interval creates useful summary", { int <- interval(ymd(20090201), ymd(20090101)) text <- c(3, "2009-01-01", "2009-02-01", "UTC", 1) names(text) <- c("Intervals", "Earliest endpoint", "Latest endpoint", "Time zone", "NA's") expect_equal(summary(c(int, int, int, as.interval(NA))), text) }) test_that("as.interval handles NAs", { expect_equal(as.interval(NA), interval(NA, NA)) }) test_that("c.interval works as expected", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 15:03:39", tz = "UTC") int <- interval(time1, time2) ints <- interval(c(time1, time1), c(time2, time2)) nants <- interval(c(time1, NA), c(time2, NA)) expect_equal(c(int, int), ints) expect_equal(c(int, NA), nants) }) test_that("%--% works as expected", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 15:03:39", tz = "UTC") int <- interval(time1, time2) attempt <- time1 %--% time2 expect_equal(attempt, int) }) test_that("int_start and int_end work as expected", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 15:03:39", tz = "UTC") int1 <- interval(time1, time2) int2 <- interval(time2, time1) expect_equal(int_start(int1), time1) expect_equal(int_start(int2), time2) expect_equal(int_start(c(int1, int2)), c(time1, time2)) expect_equal(int_end(int1), time2) expect_equal(int_end(int2), time1) expect_equal(int_end(c(int2, int1)), c(time1, time2)) }) test_that("int_length works as expected", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- time1 + 1111 time3 <- time1 - 5555 int <- interval(time1, time2) int2 <- interval(time1, time3) expect_equal(int_length(int), 1111) expect_equal(int_length(int2), -5555) expect_equal(int_length(c(int, int2)), c(1111, -5555)) }) test_that("int_shift works as expected", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2002-01-01", tz = "UTC") int <- interval(time1, time2) int2 <- interval(time2, time1) dur <- duration(seconds = 11*24*60*60) dur2 <- duration(seconds = -3600) dint <- interval(time1 + 11*24*60*60, time2 + 11*24*60*60) dint2 <- interval(time2 + 11*24*60*60, time1 + 11*24*60*60) nint <- interval(time1 - 3600, time2 - 3600) nint2 <- interval(time2 - 3600, time1 - 3600) expect_equal(int_shift(int, dur), dint) expect_equal(int_shift(int, dur2), nint) expect_equal(int_shift(int, c(dur, dur2)), c(dint, nint)) expect_equal(int_shift(int2, dur), dint2) expect_equal(int_shift(int2, dur2), nint2) expect_equal(int_shift(int2, c(dur, dur2)), c(dint2, nint2)) expect_equal(int_shift(c(int, int2), dur), c(dint, dint2)) expect_equal(int_shift(c(int, int2), dur2), c(nint, nint2)) expect_equal(int_shift(c(int, int2), c(dur, dur2)), c(dint, nint2)) expect_equal(int_shift(c(int, int2), c(dur2, dur)), c(nint, dint2)) }) test_that("int_overlaps works as expected", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2002-01-01", tz = "UTC") time21 <- as.POSIXct("2001-06-01", tz = "UTC") time22 <- as.POSIXct("2002-06-01", tz = "UTC") time31 <- as.POSIXct("2003-01-01", tz = "UTC") time32 <- as.POSIXct("2004-01-01", tz = "UTC") int1 <- interval(time1, time2) int2 <- interval(time21, time22) int3 <- interval(time31, time32) nint1 <- interval(time2, time1) nint2 <- interval(time22, time21) nint3 <- interval(time32, time31) expect_true(int_overlaps(int1, int2)) expect_false(int_overlaps(int1, int3)) expect_equal(int_overlaps(int1, c(int2, int3)), c(TRUE, FALSE)) expect_equal(int_overlaps(c(int1, int3), int2), c(TRUE, FALSE)) expect_true(int_overlaps(nint1, nint2)) expect_false(int_overlaps(nint1, nint3)) expect_equal(int_overlaps(nint1, c(nint2, nint3)), c(TRUE, FALSE)) expect_equal(int_overlaps(c(nint1, nint3), nint2), c(TRUE, FALSE)) expect_true(int_overlaps(int1, nint2)) expect_true(int_overlaps(nint1, int2)) expect_false(int_overlaps(int1, nint3)) expect_false(int_overlaps(nint1, int3)) expect_equal(int_overlaps(int1, c(int2, nint3)), c(TRUE, FALSE)) expect_equal(int_overlaps(c(int1, nint3), nint2), c(TRUE, FALSE)) }) test_that("int_aligns works as expected", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2002-01-01", tz = "UTC") time21 <- as.POSIXct("2001-06-01", tz = "UTC") time22 <- as.POSIXct("2002-01-01", tz = "UTC") time31 <- as.POSIXct("2003-01-01", tz = "UTC") time32 <- as.POSIXct("2004-01-01", tz = "UTC") int1 <- interval(time1, time2) int2 <- interval(time21, time22) int3 <- interval(time31, time32) nint1 <- interval(time2, time1) nint2 <- interval(time22, time21) nint3 <- interval(time32, time31) expect_true(int_aligns(int1, int2)) expect_false(int_aligns(int1, int3)) expect_equal(int_aligns(int1, c(int2, int3)), c(TRUE, FALSE)) expect_equal(int_aligns(c(int1, int3), int2), c(TRUE, FALSE)) expect_true(int_aligns(nint1, nint2)) expect_false(int_aligns(nint1, nint3)) expect_equal(int_aligns(nint1, c(nint2, nint3)), c(TRUE, FALSE)) expect_equal(int_aligns(c(nint1, nint3), nint2), c(TRUE, FALSE)) expect_true(int_aligns(int1, nint2)) expect_true(int_aligns(nint1, int2)) expect_false(int_aligns(int1, nint3)) expect_false(int_aligns(nint1, int3)) expect_equal(int_aligns(int1, c(int2, nint3)), c(TRUE, FALSE)) expect_equal(int_aligns(c(int1, nint3), nint2), c(TRUE, FALSE)) }) test_that("int_diff works as expected", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2002-01-01", tz = "UTC") time3 <- as.POSIXct("2003-06-01", tz = "UTC") time4 <- as.POSIXct("2002-01-01", tz = "UTC") time5 <- as.POSIXct("2003-01-01", tz = "UTC") time6 <- as.POSIXct("2004-01-01", tz = "UTC") times <- c(time1, time2, time3, time4, time5, time6) int1 <- interval(time1, time2) int2 <- interval(time2, time3) int3 <- interval(time3, time4) int4 <- interval(time4, time5) int5 <- interval(time5, time6) ints <- c(int1, int2, int3, int4, int5) expect_equal(int_diff(times), ints) }) test_that("int_standardize works as expected", { int <- interval(ymd(20100101), ymd(20090101)) standard <- interval(ymd(20090101), ymd(20100101)) ints <- c(int, int) ints2 <- c(int, standard) standards <- c(standard, standard) expect_equal(int_standardize(int), standard) expect_equal(int_standardize(standard), standard) expect_equal(int_standardize(ints), standards) expect_equal(int_standardize(ints2), standards) expect_equal(int_standardize(standards), standards) }) test_that("int_flip works as expected", { int <- interval(ymd(20100101), ymd(20090101)) flip <- interval(ymd(20090101), ymd(20100101)) ints <- c(int, int) ints2 <- c(int, flip) flips <- c(flip, flip) flips2 <- c(flip, int) expect_equal(int_flip(int), flip) expect_equal(int_flip(ints), flips) expect_equal(int_flip(ints2), flips2) expect_equal(int_flip(flip), int) expect_equal(int_flip(flips), ints) expect_equal(int_flip(flips2), ints2) }) test_that("intersect.Interval works as expected", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2002-01-01", tz = "UTC") time21 <- as.POSIXct("2001-06-01", tz = "UTC") time22 <- as.POSIXct("2002-06-01", tz = "UTC") time31 <- as.POSIXct("2003-01-01", tz = "UTC") time32 <- as.POSIXct("2004-01-01", tz = "UTC") int1 <- interval(time1, time2) int2 <- interval(time21, time22) int3 <- interval(time31, time32) nint1 <- interval(time2, time1) nint2 <- interval(time22, time21) nint3 <- interval(time32, time31) expect_equal(intersect(int1, int2), interval(time21, time2)) expect_equal(intersect(int1, int3), interval(NA, NA, tz = "UTC")) expect_equal(intersect(int1, c(int2, int3)), interval(c(time21, NA), c(time2, NA))) expect_equal(intersect(c(int1, int3), int2), interval(c(time21, NA), c(time2, NA))) expect_equal(intersect(c(int1, int3), c(int2, int2)), interval(c(time21, NA), c(time2, NA))) expect_equal(intersect(nint1, nint2), interval(time2, time21)) expect_equal(intersect(nint1, nint3), interval(NA, NA, tz = "UTC")) expect_equal(intersect(nint1, c(nint2, nint3)), interval(c(time2, NA), c(time21, NA))) expect_equal(intersect(c(nint1, nint3), nint2), interval(c(time2, NA), c(time21, NA))) expect_equal(intersect(c(nint1, nint3), c(nint2, nint2)), interval(c(time2, NA), c(time21, NA))) expect_equal(intersect(int1, nint2), interval(time21, time2)) expect_equal(intersect(nint1, nint2), interval(time2, time21)) expect_equal(intersect(int1, nint3), interval(NA, NA, tz = "UTC")) expect_equal(intersect(nint1, int3), interval(NA, NA, tz = "UTC")) expect_equal(intersect(int1, c(nint2, int3)), interval(c(time21, NA), c(time2, NA))) expect_equal(intersect(nint1, c(int2, int3)), interval(c(time2, NA), c(time21, NA))) expect_equal(intersect(c(int1, nint3), nint2), interval(c(time21, NA), c(time2, NA))) expect_equal(intersect(c(nint1, int3), nint2), interval(c(time2, NA), c(time21, NA))) expect_equal(intersect(c(int1, nint3), int2), interval(c(time21, NA), c(time2, NA))) expect_equal(intersect(c(nint1, int3), int2), interval(c(time2, NA), c(time21, NA))) expect_equal(intersect(c(int1, nint3), c(nint2, int2)), interval(c(time21, NA), c(time2, NA))) expect_equal(intersect(c(nint1, int3), c(int2, nint2)), interval(c(time2, NA), c(time21, NA))) }) test_that("union.Interval works as expected", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2002-01-01", tz = "UTC") time21 <- as.POSIXct("2001-06-01", tz = "UTC") time22 <- as.POSIXct("2002-06-01", tz = "UTC") time31 <- as.POSIXct("2003-01-01", tz = "UTC") time32 <- as.POSIXct("2004-01-01", tz = "UTC") int1 <- interval(time1, time2) int2 <- interval(time21, time22) int3 <- interval(time31, time32) nint1 <- interval(time2, time1) nint2 <- interval(time22, time21) nint3 <- interval(time32, time31) expect_equal(suppressMessages(union(int1, int2)), interval(time1, time22)) expect_equal(suppressMessages(union(int1, int3)), interval(time1, time32)) expect_equal(suppressMessages(union(int3, int1)), interval(time1, time32)) expect_equal(suppressMessages(union(int1, c(int2, int3))), interval(c(time1, time1), c(time22, time32))) expect_equal(suppressMessages(union(c(int1, int3), int2)), interval(c(time1, time21), c(time22, time32))) expect_equal(suppressMessages(union(c(int1, int3), c(int2, int1))), interval(c(time1, time1), c(time22, time32))) expect_equal(suppressMessages(union(nint1, nint2)), interval(time22, time1)) expect_equal(suppressMessages(union(nint1, nint3)), interval(time32, time1)) expect_equal(suppressMessages(union(nint3, nint1)), interval(time32, time1)) expect_equal(suppressMessages(union(nint1, c(nint2, nint3))), interval(c(time22, time32), c(time1, time1))) expect_equal(suppressMessages(union(c(nint1, nint3), nint2)), interval(c(time22, time32), c(time1, time21))) expect_equal(suppressMessages(union(c(nint1, nint3), c(nint2, nint1))), interval(c(time22, time32), c(time1, time1))) expect_equal(suppressMessages(union(int1, nint2)), interval(time1, time22)) expect_equal(suppressMessages(union(nint1, int2)), interval(time22, time1)) expect_equal(suppressMessages(union(int1, nint3)), interval(time1, time32)) expect_equal(suppressMessages(union(nint1, int3)), interval(time32, time1)) expect_equal(suppressMessages(union(int3, nint1)), interval(time1, time32)) expect_equal(suppressMessages(union(nint3, int1)), interval(time32, time1)) expect_equal(suppressMessages(union(int1, c(nint2, nint3))), interval(c(time1, time1), c(time22, time32))) expect_equal(suppressMessages(union(nint1, c(int2, int3))), interval(c(time22, time32), c(time1, time1))) expect_equal(suppressMessages(union(nint1, c(int2, nint3))), interval(c(time22, time32), c(time1, time1))) expect_equal(suppressMessages(union(c(int1, int3), nint2)), interval(c(time1, time21), c(time22, time32))) expect_equal(suppressMessages(union(c(nint1, nint3), int2)), interval(c(time22, time32), c(time1, time21))) expect_equal(suppressMessages(union(c(int1, nint3), nint2)), interval(c(time1, time32), c(time22, time21))) expect_equal(suppressMessages(union(c(int1, int3), c(nint2, nint1))), interval(c(time1, time1), c(time22, time32))) expect_equal(suppressMessages(union(c(nint1, nint3), c(int2, int1))), interval(c(time22, time32), c(time1, time1))) expect_equal(suppressMessages(union(c(int1, nint3), c(nint2, int1))), interval(c(time1, time32), c(time22, time1))) }) test_that("setdiff.Interval works as expected", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2002-01-01", tz = "UTC") time21 <- as.POSIXct("2001-06-01", tz = "UTC") time22 <- as.POSIXct("2002-06-01", tz = "UTC") time31 <- as.POSIXct("2003-01-01", tz = "UTC") time32 <- as.POSIXct("2004-01-01", tz = "UTC") int1 <- interval(time1, time2) int2 <- interval(time21, time22) int3 <- interval(time31, time32) nint1 <- interval(time2, time1) nint2 <- interval(time22, time21) nint3 <- interval(time32, time31) arrive <- ymd_hms("2011-06-04 12:00:00", tz = "Pacific/Auckland") leave <- ymd_hms("2011-08-10 14:00:00", tz = "Pacific/Auckland") auckland <- interval(arrive, leave) jsm2 <- interval(ymd(20110720, tz = "Pacific/Auckland"), ymd(20110731, tz = "Pacific/Auckland")) expect_equal(setdiff(int1, int2), interval(time1, time21)) expect_equal(setdiff(int1, int3), int1) expect_equal(setdiff(int1, c(int2, int3)), c(interval(time1, time21), int1)) expect_equal(setdiff(c(int1, int3), int2), c(interval(time1, time21), int3)) expect_equal(setdiff(c(int1, int3), c(int2, int2)), c(interval(time1, time21), int3)) expect_equal(setdiff(nint1, nint2), interval(time21, time1)) expect_equal(setdiff(nint1, nint3), nint1) expect_equal(setdiff(nint1, c(nint2, nint3)), c(interval(time21, time1), nint1)) expect_equal(setdiff(c(nint1, nint3), nint2), c(interval(time21, time1), nint3)) expect_equal(setdiff(c(nint1, nint3), c(nint2, nint2)), c(interval(time21, time1), nint3)) expect_equal(setdiff(int1, nint2), interval(time1, time21)) expect_equal(setdiff(nint1, int2), interval(time21, time1)) expect_equal(setdiff(int1, nint3), int1) expect_equal(setdiff(nint1, int3), nint1) expect_equal(setdiff(int1, c(nint2, nint3)), c(interval(time1, time21), int1)) expect_equal(setdiff(nint1, c(int2, int3)), c(interval(time21, time1), nint1)) expect_equal(setdiff(int1, c(nint2, int3)), c(interval(time1, time21), int1)) expect_equal(setdiff(nint1, c(int2, nint3)), c(interval(time21, time1), nint1)) expect_equal(setdiff(c(int1, int3), nint2), c(interval(time1, time21), int3)) expect_equal(setdiff(c(nint1, nint3), int2), c(interval(time21, time1), nint3)) expect_equal(setdiff(c(nint1, int3), nint2), c(interval(time21, time1), int3)) expect_equal(setdiff(c(int1, int3), c(nint2, nint2)), c(interval(time1, time21), int3)) expect_equal(setdiff(c(nint1, nint3), c(int2, int2)), c(interval(time21, time1), nint3)) expect_equal(setdiff(c(int1, nint3), c(nint2, int2)), c(interval(time1, time21), nint3)) expect_error(setdiff(auckland, jsm2), "Cases 1 result in discontinuous intervals.") }) test_that("%within% works as expected", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2003-01-01", tz = "UTC") time3 <- as.POSIXct("2001-06-01", tz = "UTC") time4 <- as.POSIXct("2002-06-01", tz = "UTC") time5 <- as.POSIXct("2003-01-01", tz = "UTC") time6 <- as.POSIXct("2004-01-01", tz = "UTC") time7 <- as.POSIXct("2003-01-02", tz = "UTC") base <- interval(time1, time2) ins <- interval(time3, time4) bord <- interval(time5, time6) olap <- interval(time4, time6) outs <- interval(time7, time6) nbase <- interval(time2, time1) nins <- interval(time4, time3) nbord <- interval(time6, time5) nolap <- interval(time6, time4) nouts <- interval(time6, time7) expect_true(ins %within% base) expect_false(outs %within% base) expect_false(bord %within% base) expect_false(olap %within% base) expect_true(nins %within% nbase) expect_false(nouts %within% nbase) expect_false(nbord %within% nbase) expect_false(nolap %within% nbase) expect_true(ins %within% nbase) expect_false(outs %within% nbase) expect_false(bord %within% nbase) expect_false(olap %within% nbase) expect_true(nins %within% base) expect_false(nouts %within% base) expect_false(nbord %within% base) expect_false(nolap %within% base) }) test_that("%with% recycles both arguments", { blackouts<- c(interval(ymd("2014-12-30"), ymd("2014-12-31")), interval(ymd("2014-12-30"), ymd("2015-01-03"))) testdates <-c(ymd("2014-12-20", ymd("2014-12-30"), ymd("2015-01-01"), ymd("2015-01-03"))) expect_equal(testdates %within% blackouts, c(F, T, F, T)) }) test_that("%with% works with list of intervals", { testdates <-ymd(c("2014-12-20", "2014-12-30", "2015-01-01", "2015-01-03")) blackouts<- list(interval(ymd("2014-12-30"), ymd("2014-12-31")), interval(ymd("2014-12-30"), ymd("2015-01-03"))) expect_equal(testdates %within% blackouts, c(F, T, T, T)) testdates <-c(ymd(c("2014-12-20", "2014-12-30", "2015-01-01", "2015-01-03"), tz = "UTC")) blackouts<- list(interval(ymd("2014-12-30"), ymd("2014-12-31")), interval(ymd("2014-12-30"), ymd("2015-01-03"))) expect_equal(testdates %within% blackouts, c(F, T, T, T)) }) test_that("%% on interval uses m+ arithmetic", { ## From https://github.com/tidyverse/lubridate/issues/633 start <- c("2016-04-29 12:00:00 GMT", "2013-10-31 12:00:00 GMT", "2012-05-31 12:00:00 GMT", "2010-06-29 12:00:00 GMT", "2014-12-31 12:00:00 GMT", "2015-08-31 12:00:00 GMT", "2013-03-29 12:00:00 GMT", "2014-07-31 12:00:00 GMT") end <- c("2017-03-25", "2014-03-16", "2012-12-15", "2011-03-25", "2015-10-16", "2016-03-16", "2014-03-28", "2015-07-22") x <- as.POSIXct(start) int <- interval(x, end) n <- int %/% months(1) expect_true(!any(is.na(int %% months(1)))) }) test_that("summary.Interval creates useful summary", { time1 <- as.POSIXct("2001-01-01", tz = "UTC") time2 <- as.POSIXct("2003-01-01", tz = "UTC") int <- interval(time1, time2) text <- structure(c("1", "2001-01-01", "2003-01-01", "UTC", "1"), .Names = c("Intervals", "Earliest endpoint", "Latest endpoint", "Time zone", "NA's")) expect_equal(summary(c(int, NA)), text) }) test_that("intersect on intervals propagates NAs (#226)", { expect_equal(intersect(c(interval("2014-01-15", "2014-01-16"), interval("2014-01-15", "2014-01-16")), c(interval(NA, NA), interval(NA, NA))), c(interval(NA, NA), interval(NA, NA))) expect_equal(intersect(c(interval("2014-01-15", "2014-01-16"), interval("2014-01-15", "2014-01-16"), interval("2014-01-01", "2014-01-30")), c(interval(NA, NA), interval(NA, NA), interval("2014-01-15", "2014-02-16"))), c(interval(NA, NA), interval(NA, NA), interval("2014-01-15", "2014-01-30"))) }) test_that("Reduce works with intervals (#348)", { ints <- c( interval(ymd("2001-01-01"), ymd("2002-01-01")), interval(ymd("2001-01-01"), ymd("2004-01-01")), interval(ymd("2001-02-01"), ymd("2002-01-01")) ) expect_equal(Reduce(union, ints), interval(ymd("2001-01-01"), ymd("2004-01-01"))) }) test_that("Intervals handles missing numbers", { int <- new("Interval" , .Data = c(NA, NA, NA, 123552000, 71020800, 82425600) , start = structure(c(NA, NA, NA, 1174953600, 1364428800, 1183334400), class = c("POSIXct", "POSIXt"), tzone = "UTC") , tzone = "UTC") out <- new("Interval" , .Data = c(NA, NA, NA, 31622400, NA, 31622400) , start = structure(c(NA, NA, NA, 1199145600, NA, 1199145600), tzone = "UTC", class = c("POSIXct", "POSIXt")) , tzone = "UTC") expect_equal(intersect(int, interval("2008-01-01", "2009-01-01")), out) expect_equal(intersect(int, int), int) }) lubridate/tests/testthat/test-periods.R0000644000176200001440000003607713236356705020023 0ustar liggesuserscontext("Periods") test_that("period constructor doesn't accept non-numeric or non-character inputs", { expect_error(period(interval(ymd("2014-01-01"), ymd("2015-01-01")))) }) test_that("period parsing works", { expect_equal(period("1min 2sec 2secs 1H 2M 1d"), period(seconds = 4, minutes = 3, hours = 1, days = 1)) expect_equal(period("day day"), period(days = 2)) expect_equal(period("S M H d m y"), period(seconds = 1, minutes = 1, hours = 1, days = 1, months = 1, years = 1)) expect_equal(period("2S 3M 4H 5d 6w 7m 8y"), period(seconds = 2, minutes = 3, hours = 4, days = 5, weeks = 6, months = 7, years = 8)) expect_equal(period("K")@.Data, NA_real_) expect_equal(period("ksfdsfds")@.Data, NA_real_) }) test_that("ISO ISO 8601 period parsing works", { expect_equal(period("")@.Data, NA_real_) expect_equal(period("P")@.Data, NA_real_) expect_equal(period("P3Y6M4DT12H30M5S"), period(years = 3, months = 6, days = 4, hours = 12, minutes = 30, seconds = 5)) expect_equal(period("P23DT23H"), period(days = 23, hours = 23)) expect_equal(period("P23DT60H"), period(days = 23, hours = 60)) expect_equal(period("P23DT60H20minutes 100 sec"), period(days = 23, hours = 60, minutes = 20, seconds = 100)) expect_equal(period(c("P23DT23H", "PT0S", "P0D")), period(days = c(23, 0, 0), hours = c(23, 0, 0))) }) test_that("fractional parsing works as expected", { expect_equal(period("1.1min 2.3sec 2.3secs 1.0H 2.2M 1.5d"), period(seconds = 43222.6, minutes = 3, hours = 1, days = 1)) expect_equal(period("day 1.2days"), period(days = 2, seconds = 17280)) }) test_that("is.period works", { expect_that(is.period(234), is_false()) expect_that(is.period(as.POSIXct("2008-08-03 13:01:59", tz = "UTC")), is_false()) expect_that(is.period(as.POSIXlt("2008-08-03 13:01:59", tz = "UTC")), is_false()) expect_that(is.period(Sys.Date()), is_false()) expect_that(is.period(minutes(1)), is_true()) expect_that(is.period(dminutes(1)), is_false()) expect_that(is.period(interval( as.POSIXct("2008-08-03 13:01:59", tz = "UTC"), as.POSIXct("2009-08-03 13:01:59", tz = "UTC"))), is_false()) }) test_that("is.period handles vectors", { expect_that(is.period(minutes(1:3)), is_true()) }) test_that("period works as expected", { per <- period(second = 90, minute = 5) expect_is(per, "Period") expect_equal(period(hours = 25), hours(25)) expect_equal(per@year, 0) expect_equal(per@month, 0) expect_equal(per@day, 0) expect_equal(per@hour, 0) expect_equal(per@minute, 5) expect_equal(per@.Data, 90) }) test_that("period works as expected", { per <- period(c(90, 5), c("second", "minute")) expect_is(per, "Period") expect_equal(period(hours = 25), hours(25)) expect_equal(per@year, 0) expect_equal(per@month, 0) expect_equal(per@day, 0) expect_equal(per@hour, 0) expect_equal(per@minute, 5) expect_equal(per@.Data, 90) }) test_that("period handles vector input", { per <- period(second = c(90, 60), minute = 5) expect_is(per, "Period") expect_equal(length(per), 2) expect_equal(per@year, c(0, 0)) expect_equal(per@month, c(0, 0)) expect_equal(per@day, c(0, 0)) expect_equal(per@hour, c(0, 0)) expect_equal(per@minute, c(5, 5)) expect_equal(per@.Data, c(90, 60)) }) test_that("period objects handle vector input", { x <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") expect_that(as.numeric(x + minutes(c(1, 3, 4))), equals(as.numeric(x + c(60, 180, 240)))) }) test_that("format.Period works as expected", { per <- period(second = 90, minute = 5) per2 <- period(days = 0) per3 <- period(years = 1, days = NA) expect_match(format(per), "5M 90S") expect_match(format(per2), "0S") expect_equivalent(format(per3), as.character(NA)) }) test_that("as.numeric and as.duration correctly handle periods", { tt <- period(24, "hours") + period(60, "minutes") expect_equal(as.numeric(tt, "hour"), 25) tt <- period(hours = 24, minutes = 6) expect_equal(as.numeric(tt, "hour"), 24.1) expect_equal(as.numeric(tt, "hour"), as.numeric(as.duration(tt), "hour")) }) test_that("as.period handles interval objects", { start <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") end <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") int <- interval(start, end) int_neg <- interval(end, start) expect_that(as.period(int), equals(years(1))) expect_that(as.period(int_neg), equals(years(-1))) }) test_that("as.period handles intervals across years correctly", { ## https://github.com/hadley/lubridate/issues/371 t1 <- ymd("1985-11-30") t2 <- ymd("1986-02-01") expect_equal(t2, t1 + as.period(interval(t1, t2))) ## negative t1 <- ymd("1986-02-01") t2 <- ymd("1985-11-30") expect_equal(t2, t1 + as.period(interval(t1, t2))) t1 <- "1985-11-01" t2 <- "2007-08-01" as.period(interval(t1, t2)) ymd(t1) + as.period(interval(t1, t2, "UTC")) ## negative t1 <- "2007-08-01" t2 <- "1985-11-01" as.period(interval(t1, t2)) ymd(t1) + as.period(interval(t1, t2, "UTC")) t1 <- ymd("1986-02-01") t2 <- ymd("1986-01-05") expect_equal(t2, t1 + as.period(interval(t1, t2))) }) test_that("as.period handles vector interval objects", { ## https://github.com/hadley/lubridate/issues/349 ints <- c(interval(ymd("2001-01-01"), ymd("2002-01-01")), interval(ymd("2001-01-01"), ymd("2004-01-01"))) expect_equal(as.period(ints), period(years = c(1, 3))) ints <- c(interval(ymd("2001-01-01"), ymd("2002-03-05")), interval(ymd("2001-01-01"), ymd_hms("2004-12-31 3:2:1"))) expect_equal(as.period(ints), period(years = c(1, 3), months = c(2, 11), days = c(4, 30), hours = c(0, 3), minutes = c(0, 2), seconds = c(0, 1))) }) test_that("as.period handles don't produce negative periods", { p2 <- as.period(interval(ymd("1985-12-31"), ymd("1986-02-01"))) expect_equal(month(p2), 1) p3 <- as.period(interval(ymd("1985-12-31"), ymd("1986-03-01"))) expect_equal(month(p3), 2) expect_equal(day(p3), 1) }) test_that("as.period handles interval objects with special start dates", { start <- ymd("1992-02-29") end <- ymd("2010-12-05") int <- interval(start, end) expect_that(as.period(int), equals(period(c(18, 9, 6), c("year", "month", "day")))) expect_that(as.period(int) + start, equals(end)) }) test_that("as.period with different units handles interval objects", { start <- ymd("1992-02-29") end <- ymd_hms("2010-12-05 01:02:03") int <- interval(start, end) expect_that(as.period(int), equals(period(c(18, 9, 6, 1, 2, 3), c("year", "month", "day", "hour", "minute", "second")))) expect_that(as.period(int) + start, equals(end)) expect_that(as.period(int, "months"), equals(period(c(225, 6, 1, 2, 3), c("month", "day", "hour", "minute", "second")))) expect_that(as.period(int, "months") + start, equals(end)) expect_that(as.period(int, "hours"), equals(period(c(164497, 2, 3), c("hour", "minute", "second")))) expect_that(as.period(int, "hours") + start, equals(end)) expect_that(as.period(int, "minute"), equals(period(c(9869822, 3), c("minute", "second")))) expect_that(as.period(int, "minute") + start, equals(end)) expect_that(as.period(int, "second"), equals(period(c(592189323), c("second")))) expect_that(as.period(int, "second") + start, equals(end)) }) test_that("as.period with different units handles negative interval objects", { end <- ymd("1992-02-29", tz = "UTC") start <- ymd_hms("2010-12-05 01:02:03") int <- interval(start, end) expect_that(as.period(int), equals(period(-c(18, 9, 5, 1, 2, 3), c("year", "month", "day", "hour", "minute", "second")))) expect_that(as.period(int) + start, equals(end)) expect_that(as.period(int, "months"), equals(period(-c(225, 5, 1, 2, 3), c("month", "day", "hour", "minute", "second")))) expect_that(as.period(int, "months") + start, equals(end)) expect_that(as.period(int, "hours"), equals(period(-c(164497, 2, 3), c("hour", "minute", "second")))) expect_that(as.period(int, "hours") + start, equals(end)) expect_that(as.period(int, "minute"), equals(period(-c(9869822, 3), c("minute", "second")))) expect_that(as.period(int, "minute") + start, equals(end)) expect_that(as.period(int, "second"), equals(period(-c(592189323), c("second")))) expect_that(as.period(int, "second") + start, equals(end)) }) test_that("as.period handles tricky intervals", { expect_equal( as.period(interval(ymd("1986-01-31"), ymd("1986-02-01"))) , period(days = 1)) expect_equal( as.period(interval(ymd("1984-01-30"), ymd("1986-02-01"))) , period(years = 2, days = 2)) expect_equal( as.period(interval(ymd("1984-01-30"), ymd("1986-03-01"))) , period(years = 2, months = 1, days = 1)) expect_equal( as.period(interval(ymd("1985-01-30"), ymd("1986-03-30"))) , period(years = 1, months = 2)) expect_equal( as.period(interval(ymd("1985-01-28"), ymd("1986-03-28"))) , period(years = 1, months = 2)) expect_equal( as.period(interval(ymd("1985-01-31"), ymd("1986-03-28"))) , period(years = 1, months = 1, days = 28)) expect_equal( as.period(interval(ymd("1984-01-28"), ymd("1984-02-28"))) , period(months = 1)) expect_equal( as.period(interval(ymd("1984-01-28"), ymd("1984-02-29"))) , period(months = 1, days = 1)) expect_equal( as.period(interval(ymd_hms("1984-01-28 5:0:0"), ymd_hms("1984-02-29 3:0:0"))) , period(months = 1, hours = 22)) expect_equal( as.period(interval(ymd("1984-01-28"), ymd("1984-03-01"))) , period(months = 1, days = 2)) expect_equal( as.period(interval(ymd_hms("1984-01-28 5:0:0"), ymd_hms("1984-03-01 3:0:0"))) , period(months = 1, days = 1, hours = 22)) }) test_that("as.period handles tricky negative intervals", { expect_equal( as.period(interval(ymd("1986-02-01"), ymd("1986-01-31"))) , period(days = -1)) expect_equal( as.period(interval(ymd("1986-02-01"), ymd("1984-01-30"))) , period(years = -2, days = -2)) expect_equal( as.period(interval(ymd("1986-03-01"), ymd("1984-01-30"))) , period(years = -2, months = -1, days = -2)) expect_equal( as.period(interval(ymd("1986-03-30"), ymd("1985-01-30"))) , period(years = -1, months = -2)) expect_equal( as.period(interval(ymd("1986-03-28"), ymd("1985-01-28"))) , period(years = -1, months = -2)) expect_equal( as.period(interval(ymd("1986-03-28"), ymd("1985-01-31"))) , period(years = -1, months = -1, days = -28)) expect_equal( as.period(interval(ymd("1986-02-01"), ymd("1985-12-31"))) , period(months = -1, days = -1)) expect_equal( as.period(interval(ymd("1984-03-01"), ymd("1984-01-31"))) , period(months = -1, days = -1)) expect_equal( as.period(interval(ymd("1984-03-01"), ymd("1984-01-30"))) , period(months = -1, days = -2)) expect_equal( as.period(interval(ymd("1984-03-01"), ymd("1984-01-29"))) , period(months = -1, days = -3)) expect_equal( as.period(interval(ymd_hms("1984-03-01 3:0:0"), ymd_hms("1984-01-28 5:0:0"))) , period(months = -1, days = -3, hours = -22)) }) test_that("as.period handles NA in interval objects", { one_missing_date <- as.POSIXct(NA_real_, origin = origin) one_missing_interval <- interval(one_missing_date, one_missing_date) several_missing_dates <- rep(as.POSIXct(NA_real_, origin = origin), 2) several_missing_intervals <- interval(several_missing_dates, several_missing_dates) start_missing_intervals <- interval(several_missing_dates, origin) end_missing_intervals <- interval(origin, several_missing_dates) na.per <- period(sec = NA, min = NA, hour = NA, day = NA, month = NA, year = NA) expect_equal(as.period(one_missing_interval, "year"), na.per) expect_equal(as.period(several_missing_intervals, "year"), c(na.per, na.per)) expect_equal(as.period(start_missing_intervals, "year"), c(na.per, na.per)) expect_equal(as.period(end_missing_intervals, "year"), c(na.per, na.per)) }) test_that("as.period handles NA duration objects", { na.per <- period(sec = NA, min = NA, hour = NA, day = NA, month = NA, year = NA) expect_equal(suppressMessages(as.period(dyears(NA))), na.per) expect_equal(suppressMessages(as.period(dyears(c(NA, NA)))), c(na.per, na.per)) expect_equal(suppressMessages(as.period(dyears(c(1, NA)))), c(years(1), na.per)) }) test_that("as.period handles NA objects", { na.per <- seconds(NA) expect_equal(as.period(NA), na.per) }) test_that("as.period handles vectors", { time1 <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") time2 <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") time3 <- as.POSIXct("2010-08-03 13:01:59", tz = "UTC") int <- interval(c(time2, time1), time3) dur <- duration(seconds = 5, minutes = c(30, 59)) expect_that(as.period(int), equals(years(1:2))) expect_that(as.period(dur), equals(seconds(5) + minutes(c(30, 59)))) }) test_that("as.period handles duration objects", { dur <- duration(seconds = 5, minutes = 30) expect_that(as.period(dur), equals(seconds(5) + minutes(30))) }) test_that("as.period handles period objects", { per <- minutes(1000) + seconds(50) + seconds(11) expect_that(as.period(per), equals(per)) expect_that(as.period(per, "minute"), equals(period(c(1001, 1), c("minute", "second")))) expect_that(as.period(per, "hour"), equals(period(c(16, 41, 1), c("hour", "minute", "second")))) }) test_that("[<- can subset periods with new periods", { Time <- data.frame(Time = c(hms("01:01:01"), hms("02:02:02"))) Time[1, 1] <- Time[1, 1] + hours(1) times <- days(1:3) times[1] <- times[1] + hours(2) expect_equal(Time[1, 1], hms("02:01:01")) expect_equal(times[1], period(days = 1, hours = 2)) }) test_that("period correctly handles week units", { expect_equal(period(1, "week"), days(7)) expect_equal(period(8, "days"), days(8)) expect_equal(period(c(3, 2), c("days", "week")), days(c(17))) }) test_that("format.period correctly displays negative units", { expect_match(format(days(-2)), "-2d 0H 0M 0S") expect_match(format(period(second = -1, hour = -2, day = 3)), "3d -2H 0M -1S") }) test_that("format.Period correctly displays intervals of length 0", { per <- period(seconds = 5) expect_output(print(per[FALSE]), "Period\\(0)") }) test_that("c.Period correctly handles NAs", { per <- period(seconds = 5) expect_true(is.na(c(per, NA)[2])) }) test_that("summary.Period creates useful summary", { per <- period(minutes = 5) text <- c(rep("5M 0S", 6), 1) names(text) <- c("Min.", "1st Qu.", "Median", "Mean", "3rd Qu.", "Max.", "NA's") expect_equal(summary(c(per, NA)), text) }) test_that("idempotentcy between period_to_seconds and seconds_to_period holds", { period <- period(years = 2, months = 3, days = 4, hour = 5, minutes = 6, seconds = 7) seconds <- 71319967 expect_equal(period_to_seconds(seconds_to_period(seconds)), seconds) }) test_that("direct reation of periods works as expected", { expect_equal(new("Period", 1:4), period(seconds = 1:4)) expect_equal(new("Period", 1:4, day = 1:2), period(seconds = 1:4, days = 1:2)) }) lubridate/tests/testthat/test-difftimes.R0000644000176200001440000000122613201152061020271 0ustar liggesuserscontext("Difftimes") test_that("is.difftime works as expected", { ct_time <- as.POSIXct("2008-08-03 13:01:59", tz = "UTC") lt_time <- as.POSIXlt("2009-08-03 13:01:59", tz = "UTC") expect_true(!is.difftime(234)) expect_true(!is.difftime(ct_time)) expect_true(!is.difftime(lt_time)) expect_true(!is.difftime(Sys.Date())) expect_true(!is.difftime(minutes(1))) expect_true(!is.difftime(dminutes(1))) expect_true(!is.difftime(interval(ct_time, lt_time))) expect_true(is.difftime(make_difftime(1000))) expect_true(is.difftime(ct_time - lt_time)) }) test_that("is.difftime handle vectors", { expect_true(is.difftime(make_difftime(1:3))) }) lubridate/tests/testthat/test-parsers.R0000644000176200001440000014256713263145226020031 0ustar liggesuserscontext("Parsing") Sys.setlocale("LC_TIME", "C") test_that("ymd functions correctly parse dates separated by -", { expect_that(ymd("2010-01-02"), equals(as.Date("2010-01-02"))) expect_that(ymd("10-01-02"), equals(as.Date("2010-01-02"))) expect_that(ydm("2010-02-01"), equals(as.Date("2010-01-02"))) expect_that(mdy("01-02-2010"), equals(as.Date("2010-01-02"))) expect_that(myd("01-2010-02"), equals(as.Date("2010-01-02"))) expect_that(dmy("02-01-2010"), equals(as.Date("2010-01-02"))) expect_that(dym("02-2010-01"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010-01-02", "2010-01-03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) }) test_that("ymd functions correctly parse dates separated by /", { expect_that(ymd("2010/01/02"), equals(as.Date("2010-01-02"))) expect_that(ymd("10/01/02"), equals(as.Date("2010-01-02"))) expect_that(ydm("2010/02/01"), equals(as.Date("2010-01-02"))) expect_that(mdy("01/02/2010"), equals(as.Date("2010-01-02"))) expect_that(myd("01/2010/02"), equals(as.Date("2010-01-02"))) expect_that(dmy("02/01/2010"), equals(as.Date("2010-01-02"))) expect_that(dym("02/2010/01"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010/01/02", "2010/01/03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) }) test_that("ymd functions correctly parse dates separated by .", { expect_that(ymd("2010.01.02"), equals(as.Date("2010-01-02"))) expect_that(ymd("10.01.02"), equals(as.Date("2010-01-02"))) expect_that(ydm("2010.02.01"), equals(as.Date("2010-01-02"))) expect_that(mdy("01.02.2010"), equals(as.Date("2010-01-02"))) expect_that(myd("01.2010.02"), equals(as.Date("2010-01-02"))) expect_that(dmy("02.01.2010"), equals(as.Date("2010-01-02"))) expect_that(dym("02.2010.01"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010.01.02", "2010.01.03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) }) test_that("ymd functions correctly parse dates separated by ,", { expect_that(ymd("2010,01,02"), equals(as.Date("2010-01-02"))) expect_that(ymd("10,01,02"), equals(as.Date("2010-01-02"))) expect_that(ydm("2010,02,01"), equals(as.Date("2010-01-02"))) expect_that(mdy("01,02,2010"), equals(as.Date("2010-01-02"))) expect_that(myd("01,2010,02"), equals(as.Date("2010-01-02"))) expect_that(dmy("02,01,2010"), equals(as.Date("2010-01-02"))) expect_that(dym("02,2010,01"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010,01,02", "2010,01,03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) }) test_that("ymd functions correctly parse dates separated by :", { expect_that(ymd("2010:01:02"), equals(as.Date("2010-01-02"))) expect_that(ymd("10:01:02"), equals(as.Date("2010-01-02"))) expect_that(ydm("2010:02:01"), equals(as.Date("2010-01-02"))) expect_that(mdy("01:02:2010"), equals(as.Date("2010-01-02"))) expect_that(myd("01:2010:02"), equals(as.Date("2010-01-02"))) expect_that(dmy("02:01:2010"), equals(as.Date("2010-01-02"))) expect_that(dym("02:2010:01"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010:01:02", "2010:01:03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) }) test_that("ymd functions correctly parse dates with no separators", { expect_that(ymd("20100102"), equals(as.Date("2010-01-02"))) expect_that(ydm("20100201"), equals(as.Date("2010-01-02"))) expect_that(mdy("01022010"), equals(as.Date("2010-01-02"))) expect_that(myd("01201002"), equals(as.Date("2010-01-02"))) expect_that(dmy("02012010"), equals(as.Date("2010-01-02"))) expect_that(dym("02201001"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("20100102", "20100103")), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd("100102"), equals(as.Date("2010-01-02"))) expect_that(ymd("20100102"), equals(as.Date("2010-01-02"))) expect_that(ydm("20100201"), equals(as.Date("2010-01-02"))) expect_that(mdy("01022010"), equals(as.Date("2010-01-02"))) expect_that(myd("01201002"), equals(as.Date("2010-01-02"))) expect_that(dmy("02012010"), equals(as.Date("2010-01-02"))) expect_that(dym("02201001"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("20100102", "20100103")), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd("100102"), equals(as.Date("2010-01-02"))) }) test_that("ymd functions correctly parse dates with no separators", { expect_that(ymd("20100102"), equals(as.Date("2010-01-02"))) expect_that(ydm("20100201"), equals(as.Date("2010-01-02"))) expect_that(mdy("01022010"), equals(as.Date("2010-01-02"))) expect_that(myd("01201002"), equals(as.Date("2010-01-02"))) expect_that(dmy("02012010"), equals(as.Date("2010-01-02"))) expect_that(dym("02201001"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("20100102", "20100103")), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd("100102"), equals(as.Date("2010-01-02"))) expect_that(ymd("20100102"), equals(as.Date("2010-01-02"))) expect_that(ydm("20100201"), equals(as.Date("2010-01-02"))) expect_that(mdy("01022010"), equals(as.Date("2010-01-02"))) expect_that(myd("01201002"), equals(as.Date("2010-01-02"))) expect_that(dmy("02012010"), equals(as.Date("2010-01-02"))) expect_that(dym("02201001"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("20100102", "20100103")), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd("100102"), equals(as.Date("2010-01-02"))) }) test_that("ymd parser warns on failed parsing", { expect_warning(ymd("2018-02-30", quiet = FALSE), ".*failed to parse") }) test_that("ymd function correctly parse b and B formats", { expect_equal(ymd("2004-Jan-15"), as.Date("2004-01-15")) expect_equal(ymd("2004-January-15"), as.Date("2004-01-15")) expect_equal(ymd("2004-Jan-15", "2004-Feb-15", "1904-Jan-15", "1904-Feb-15"), as.Date(c("2004-01-15 UTC", "2004-02-15 UTC", "1904-01-15 UTC", "1904-02-15 UTC"))) expect_equal(ymd("2004-Jan-15", "2004-Feb-15", "1904-January-15", "1904-February-15"), as.Date(c("2004-01-15 UTC", "2004-02-15 UTC", "1904-01-15 UTC", "1904-02-15 UTC"))) expect_equal(mdy("Jan-15-2004"), as.Date("2004-01-15")) expect_equal(mdy("January-15-2004"), as.Date("2004-01-15")) expect_equal(mdy("Jan-15-2004", "Feb-15-2004", "Jan-15-1904", "Feb-15-1904"), as.Date(c("2004-01-15 UTC", "2004-02-15 UTC", "1904-01-15 UTC", "1904-02-15 UTC"))) expect_equal(mdy("Jan-15-2004", "Feb-15-2004", "January-15-1904", "February-15-1904"), as.Date(c("2004-01-15 UTC", "2004-02-15 UTC", "1904-01-15 UTC", "1904-02-15 UTC"))) }) test_that("ymd function correctly parse b and B formats", { expect_equal(ymd("2004-Jan-15"), as.Date("2004-01-15")) expect_equal(ymd("2004-January-15"), as.Date("2004-01-15")) expect_equal(ymd("2004-Jan-15", "2004-Feb-15", "1904-Jan-15", "1904-Feb-15"), as.Date(c("2004-01-15 UTC", "2004-02-15 UTC", "1904-01-15 UTC", "1904-02-15 UTC"))) expect_equal(ymd("2004-Jan-15", "2004-Feb-15", "1904-January-15", "1904-February-15"), as.Date(c("2004-01-15 UTC", "2004-02-15 UTC", "1904-01-15 UTC", "1904-02-15 UTC"))) expect_equal(mdy("Jan-15-2004"), as.Date("2004-01-15")) expect_equal(mdy("January-15-2004"), as.Date("2004-01-15")) expect_equal(mdy("Jan-15-2004", "Feb-15-2004", "Jan-15-1904", "Feb-15-1904"), as.Date(c("2004-01-15 UTC", "2004-02-15 UTC", "1904-01-15 UTC", "1904-02-15 UTC"))) expect_equal(mdy("Jan-15-2004", "Feb-15-2004", "January-15-1904", "February-15-1904"), as.Date(c("2004-01-15 UTC", "2004-02-15 UTC", "1904-01-15 UTC", "1904-02-15 UTC"))) }) test_that("ymd functions correctly parse dates with no separators and b and B formats", { expect_that(ymd("2010January02"), equals(as.Date("2010-01-02"))) expect_that(ydm("201002January"), equals(as.Date("2010-01-02"))) expect_that(mdy("January022010"), equals(as.Date("2010-01-02"))) expect_that(myd("January201002"), equals(as.Date("2010-01-02"))) expect_that(dmy("02January2010"), equals(as.Date("2010-01-02"))) expect_that(dym("022010January"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010January02", "2010January03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd("10January02"), equals(as.Date("2010-01-02"))) expect_that(ymd("2010January02"), equals(as.Date("2010-01-02"))) expect_that(ydm("201002January"), equals(as.Date("2010-01-02"))) expect_that(mdy("January022010"), equals(as.Date("2010-01-02"))) expect_that(myd("January201002"), equals(as.Date("2010-01-02"))) expect_that(dmy("02January2010"), equals(as.Date("2010-01-02"))) expect_that(dym("022010January"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010January02", "2010January03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd("10January02"), equals(as.Date("2010-01-02"))) expect_that(ymd("2010Jan02"), equals(as.Date("2010-01-02"))) expect_that(ydm("201002Jan"), equals(as.Date("2010-01-02"))) expect_that(mdy("Jan022010"), equals(as.Date("2010-01-02"))) expect_that(myd("Jan201002"), equals(as.Date("2010-01-02"))) expect_that(dmy("02Jan2010"), equals(as.Date("2010-01-02"))) expect_that(dym("022010Jan"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010Jan02", "2010Jan03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd("10Jan02"), equals(as.Date("2010-01-02"))) expect_that(ymd("2010Jan02"), equals(as.Date("2010-01-02"))) expect_that(ydm("201002Jan"), equals(as.Date("2010-01-02"))) expect_that(mdy("Jan022010"), equals(as.Date("2010-01-02"))) expect_that(myd("Jan201002"), equals(as.Date("2010-01-02"))) expect_that(dmy("02Jan2010"), equals(as.Date("2010-01-02"))) expect_that(dym("022010Jan"), equals(as.Date("2010-01-02"))) expect_that(ymd(c("2010Jan02", "2010Jan03")), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd("10Jan02"), equals(as.Date("2010-01-02"))) }) test_that("ymd functions correctly parse dates with no separators and no quotes", { expect_that(ymd(20100102), equals(as.Date("2010-01-02"))) expect_that(ydm(20100201), equals(as.Date("2010-01-02"))) expect_that(mdy(01022010), equals(as.Date("2010-01-02"))) expect_that(myd(01201002), equals(as.Date("2010-01-02"))) expect_that(dmy(02012010), equals(as.Date("2010-01-02"))) expect_that(dym(02201001), equals(as.Date("2010-01-02"))) expect_that(ymd(c(20100102, 20100103)), equals(as.Date(c("2010-01-02", "2010-01-03")))) expect_that(ymd(100102), equals(as.Date("2010-01-02"))) expect_that(ymd_hms(20100102235959), equals(as.POSIXct("2010-01-02 23:59:59", tz = "UTC"))) }) test_that("all numbers are correctly converted into character for parsing", { # Conversion to character of numbers with 000000 at the end with as.character() # may outputs scientific notation depending on the value of the 'scipen' option. # .num_to_date() uses format() to avoid that. Check that it does indeed work expect_that(ymd_hms(20100102000000), equals(as.POSIXct("2010-01-02 00:00:00", tz = "UTC"))) expect_that(.num_to_date(20100102000000), equals("20100102000000")) }) test_that("ymd functions parse absurd formats as NA's", { ## should not through errors, just as as.POSIX and strptime pna <- as.Date(NA) expect_that(ymd(201001023, quiet = TRUE), equals(pna)) expect_that(ydm(20103201, quiet = TRUE), equals(pna)) expect_that(mdy(13022010, quiet = TRUE), equals(pna)) expect_that(myd(01201033, quiet = TRUE), equals(pna)) expect_that(dmy(02222010, quiet = TRUE), equals(pna)) expect_that(dym(022010013, quiet = TRUE), equals(pna)) pna <- with_tz(as.POSIXct(NA), "UTC") expect_that(ymd_hms("2010-01-023 23:59:59", quiet = TRUE), equals(pna)) expect_that(ymd_hms("2010-01-023 23:59:59.34", quiet = TRUE), equals(pna)) expect_that(ymd_hms("201001023235959.34", quiet = TRUE), equals(pna)) expect_that(ymd(c(201001024, 20100103), quiet = TRUE), equals(as.Date(c(NA, "2010-01-03")))) }) test_that("ymd functions give warning when parsing absurd formats", { ## should not through errors, just as as.POSIX and strptime expect_warning(ymd(201001023)) expect_warning(ydm(20103201)) expect_warning(mdy(13022010)) expect_warning(myd(01201033)) expect_warning(dmy(02222010)) expect_warning(dym(022010013)) expect_warning(ymd_hms("2010-01-023 23:59:59")) expect_warning(ymd_hms("2010-01-023 23:59:59.34")) expect_warning(ymd_hms("201001023235959.34")) expect_warning(ymd(c(201001024, 20100103))) }) test_that("cutoff_2000 works as expected", { dates <- c("20-02-03", "67-02-03", "68-02-03", "69-02-03", "99-02-03", "00-02-03") expect_equal(parse_date_time2(dates, "ymd"), ymd(c("2020-02-03", "2067-02-03", "2068-02-03", "1969-02-03", "1999-02-03", "2000-02-03"), tz = "UTC")) expect_equal(parse_date_time2(dates, "ymd", cutoff_2000 = 67), ymd(c("2020-02-03", "2067-02-03", "1968-02-03", "1969-02-03", "1999-02-03", "2000-02-03"), tz = "UTC")) expect_equal(parse_date_time2(dates, "ymd", cutoff_2000 = 20), ymd(c("2020-02-03", "1967-02-03", "1968-02-03", "1969-02-03", "1999-02-03", "2000-02-03"), tz = "UTC")) expect_equal(parse_date_time2(dates, "ymd", cutoff_2000 = 0), ymd(c("1920-02-03", "1967-02-03", "1968-02-03", "1969-02-03", "1999-02-03", "2000-02-03"), tz = "UTC")) expect_equal(parse_date_time2(dates, "ymd", cutoff_2000 = -1), ymd(c("1920-02-03", "1967-02-03", "1968-02-03", "1969-02-03", "1999-02-03", "1900-02-03"), tz = "UTC")) }) test_that("0 month and 0 day in date produces NA", { expect_equal(ymd(c("2013-1-1", "2013-0-1"), quiet = TRUE), as.Date(c("2013-01-01", NA))) expect_equal(ymd(c("2013-1-1", "2013-1-0"), quiet = TRUE), as.Date(c("2013-01-01", NA))) expect_equal(ymd("2013-1-0", quiet = TRUE), as.Date(as.character(NA))) }) test_that("ymd_hms correctly handles a variety of formats", { expect_that(ymd_hms("2010-01-02 23:59:59"), equals(as.POSIXct("2010-01-02 23:59:59", tz = "UTC"))) expect_that(ymd_hms("2010,01,02 23.59.59"), equals(as.POSIXct("2010-01-02 23:59:59", tz = "UTC"))) expect_that(ymd_hms("2010,01,02 23.59.59.9"), equals(as.POSIXct("2010-01-02 23:59:59.9 UTC", tz = "UTC"))) expect_that(ymd_hms("2010/01/02 23/59/59"), equals(as.POSIXct("2010-01-02 23:59:59", tz = "UTC"))) expect_that(ymd_hms("2010:01:02-23:59:59"), equals(as.POSIXct("2010-01-02 23:59:59", tz = "UTC"))) ## VS: Next doesn't parse on my machine. It's OS specific. ## expect_that(ymd_hms("2010-01-02 23:59:61"), equals(as.POSIXct( ## "2010-01-03 00:00:01", tz = "UTC"))) ## expect_that(ymd_hms(c("2010-01-02 23:59:61", ## "2010-01-02 00:00:00")), equals(as.POSIXct( ## c("2010-01-03 00:00:01", "2010-01-02 00:00:00"), tz = ## "UTC"))) expect_that(ymd_hms("10-01-02 23:59:59"), equals(as.POSIXct("2010-01-02 23:59:59", tz = "UTC"))) }) test_that("parse_date_time handles multiple month formats correctly", { dates <- c("09-01-17", "02-Sep-17") expect_equal(parse_date_time(dates, orders = c("dmy"), locale = "C"), ymd(c("2017-01-09", "2017-09-02"), tz = "UTC")) expect_equal(parse_date_time(dates, orders = c("dby"), locale = "C", quiet = T), ymd(c(NA, "2017-09-02"), tz = "UTC")) ## mdy & dby expect_equal(parse_date_time(dates, orders = c("mdy", "dby")), ymd(c("2017-09-01", "2017-09-02"), tz = "UTC")) ## mdY & dby/Y expect_equal(parse_date_time(c("09-01-2017", "02-Sep-17"), orders = c("mdY", "dby")), ymd(c("2017-09-01", "2017-09-02"), tz = "UTC")) expect_equal(parse_date_time(c("09-01-2017", "02-Sep-2017"), orders = c("mdY", "dbY")), ymd(c("2017-09-01", "2017-09-02"), tz = "UTC")) ## mdy/Y & dby/Y, with no mdy/Y in x expect_equal(parse_date_time("09-01-17", orders = c("mdy", "dby", "dbY")), ymd(c("2017-09-01"), tz = "UTC")) }) test_that("parse_date_time handles multiple partial month formats correctly", { expect_equal(parse_date_time("May-2010", orders="%b-%Y"), ymd("2010-05-01", tz = "UTC")) expect_equal(parse_date_time(c("02-May-2010", "May-2010", "2010"), orders=c("dbY", "bY", "Y")), ymd(c("2010-05-02", "2010-05-01", "2010-01-01"), tz = "UTC")) expect_equal(parse_date_time(c("02-May-2010", "May-03-2010", "05-03-2010", "May-2010", "2010"), orders=c("dbY", "bdY", "mdY", "bY", "Y")), ymd(c("2010-05-02", "2010-05-03", "2010-05-03", "2010-05-01", "2010-01-01"), tz = "UTC")) }) test_that("parse_date_time gives higher priority to y than to Y format", { expect_equal(parse_date_time(c("apr.12.50","apr.2.2016"), orders = "mdy"), ymd(c("2050-04-12 UTC", "2016-04-02 UTC"), tz = "UTC")) expect_equal(parse_date_time(c("50.apr.12","2016.apr.2"), orders = "ymd"), ymd(c("2050-04-12 UTC", "2016-04-02 UTC"), tz = "UTC")) }) test_that("C parser correctly handles month formats", { expect_equal(ymd_hms("2010-Jan-02 23:59:59"), as.POSIXct("2010-01-02 23:59:59", tz = "UTC")) expect_equal(ymd_hms("2010-January-02 23:59:59"), as.POSIXct("2010-01-02 23:59:59", tz = "UTC")) expect_equal(ymd_hms("2010-Dec-02 23:59:59"), as.POSIXct("2010-12-02 23:59:59", tz = "UTC")) expect_equal(ymd_hms("2010-Dec-02 23:59:59"), parse_date_time2("2010-Dec-02 23:59:59", "YOmdHMS")) expect_equal(ymd_hms("2010-Dec-02 23:59:59"), parse_date_time2("2010-Dec-02 23:59:59", "YbdHMS")) expect_equal(ymd_hms("2010-Dec-02 03:59:59 PM"), parse_date_time2("2010-Dec-02 15:59:59", "YbdHMS")) expect_equal(ymd_hms("2010-Dec-02 03:59:59 PM"), parse_date_time2("2010-Dec-02 03:59:59 PM", "YOmdHMSOp")) expect_equal(ymd_hms("2010-Dec-02 23:59:59"), parse_date_time2("2010-December-02 23:59:59", "YBdHMS")) yy <- c("10-Feb-28 23:59:59", "10-May-28 23:59:59", "10-September-28 23:59:59") zz <- c("2010-Feb-28 23:59:59", "2010-May-28 23:59:59", "2010-September-28 23:59:59") tt <- c("2010-02-28 23:59:59", "2010-05-28 23:59:59", "2010-09-28 23:59:59") expect_equal(parse_date_time2(yy, "ybdHMS"), as.POSIXct(tt, tz = "UTC")) expect_equal(parse_date_time2(zz, "YbdHMS"), as.POSIXct(tt, tz = "UTC")) expect_equal(parse_date_time2(yy, "ybdHMS"), as.POSIXct(tt, tz = "UTC")) expect_equal(parse_date_time2(yy, "ymdHMS"), as.POSIXct(tt, tz = "UTC")) expect_equal(parse_date_time2(zz, "YOmdHMS"), as.POSIXct(tt, tz = "UTC")) expect_equal(ymd_hms(c(yy, zz)), as.POSIXct(c(tt, tt), tz = "UTC")) }) test_that("hms functions correctly handle : separators", { expect_that(hms("3:3:3"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(hms("03:03:03"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(ms("03:03"), equals(minutes(3) + seconds(3))) expect_that(hm("03:03"), equals(hours(3) + minutes(3))) expect_that(hm("03:3"), equals(hours(3) + minutes(3))) }) test_that("hms functions correctly handle . separators", { expect_that(hms("3.3.3"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(hms("03.03.03"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(ms("03.03"), equals(minutes(3) + seconds(3))) expect_that(hm("03.03"), equals(hours(3) + minutes(3))) expect_that(hm("03.3"), equals(hours(3) + minutes(3))) }) test_that("hms functions correctly handle space separators", { expect_that(hms("3 3 3"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(hms("03 03 03"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(ms("03 03"), equals(minutes(3) + seconds(3))) expect_that(hm("03 03"), equals(hours(3) + minutes(3))) expect_that(hm("03 3"), equals(hours(3) + minutes(3))) }) test_that("hms functions correctly handle , separators", { expect_that(hms("3,3,3"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(hms("03,03,03"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(ms("03,03"), equals(minutes(3) + seconds(3))) expect_that(hm("03,03"), equals(hours(3) + minutes(3))) expect_that(hm("03,3"), equals(hours(3) + minutes(3))) }) test_that("hms functions correctly handle / separators", { expect_that(hms("3/3/3"), equals(hours(3) + minutes(3) + seconds(3))) expect_that(hms("00/00/00"), equals(hours(0) + minutes(0) + seconds(0))) expect_that(ms("03/03"), equals(minutes(3) + seconds(3))) expect_that(hm("03/03"), equals(hours(3) + minutes(3))) expect_that(hm("03/3"), equals(hours(3) + minutes(3))) }) test_that("hms functions correctly roll", { expect_equal(hms("3:59:120", roll = T), period(hours = 4, minutes = 1)) expect_equal(ms("59:125", roll = T), period(hours = 1, minutes = 1, seconds = 5)) expect_equal(hm("159:125", roll = T), period(hours = 161, minutes = 5)) }) test_that("hms functions return NA on shorter inputs", { expect_that(is.na(hms("3:3:3:4", quiet = TRUE)), is_true()) expect_that(is.na(hms("03:03", quiet = TRUE)), is_true()) expect_that(is.na(ms("03:02:01", quiet = TRUE)), is_true()) expect_that(is.na(ms("03", quiet = TRUE)), is_true()) expect_that(is.na(hm("03:03:01", quiet = TRUE)), is_true()) expect_that(is.na(hm("03", quiet = TRUE)), is_true()) }) test_that("hms functions give warning on shorter inputs", { expect_warning(hms("3:3:3:4")) expect_warning(hms("03:03")) expect_warning(ms("03:02:01")) expect_warning(ms("03")) expect_warning(hm("03:03:01")) expect_warning(hm("03")) }) test_that("hms functions correctly negative components separators", { expect_that(hms("3-3-3"), equals(hours(3) - minutes(3) - seconds(3))) expect_that(hms("03-03-03"), equals(hours(3) - minutes(3) - seconds(3))) expect_that(ms("-03-03"), equals(-minutes(3) - seconds(3))) expect_that(hm("03-3"), equals(hours(3) - minutes(3))) }) test_that("AM/PM indicators are parsed correctly", { expect_equal(parse_date_time2("12/17/1996 04:00:00 PM", "mdYHMSp"), ymd_hms("1996-12-17 16:00:00")) expect_equal(parse_date_time2("12/17/1996 04:00:00 PM", "mdYHMSOp"), ymd_hms("1996-12-17 16:00:00")) expect_equal(parse_date_time2("12/17/1996 04:00:00 AM", "mdYHMSp"), ymd_hms("1996-12-17 04:00:00")) expect_equal(parse_date_time2("12/17/1996 04:00:00 PM", "mdYHMSp", tz = "CET"), ymd_hms("1996-12-17 16:00:00", tz = "CET")) expect_equal(parse_date_time2("12/17/1996 04:00:00 TM", "mdYHMSp"), make_datetime(NA)) expect_equal(fast_strptime("1996-05-17 04:00:00 PM", "%Y-%m-%d %H:%M:%S %Op"), ymd_hms("1996-05-17 16:00:00")) expect_equal(ymd_hms("1996-05-17 04:00:00 PM"), ymd_hms("1996-05-17 16:00:00")) expect_equal(ydm_hms("1996-17-05 04:00:00 PM"), ydm_hms("1996-17-05 16:00:00")) expect_equal(dmy_hms("17-05-1996 04:00:00 PM"), dmy_hms("17-05-1996 16:00:00")) expect_equal(parse_date_time("2010-Dec-02 03:59:59 PM", "YmdT"), parse_date_time2("2010-12-02 15:59:59", "YmdHMS")) expect_equal(parse_date_time("2010-Dec-02 03:59:59 PM", "YmdT"), parse_date_time2("2010-12-02 15:59:59", "YmdHMS")) expect_equal(parse_date_time("2010-Dec-02 03:59 PM", "YmdR"), parse_date_time2("2010-12-02 15:59:00", "YmdHMS")) expect_equal(parse_date_time("2010-Dec-02 03 PM", "Ymdr"), parse_date_time2("2010-12-02 15:00:00", "YmdHMS")) }) test_that("AM/PM is parse correctly", { raw <- c("09/17/2015 02:55:00 PM", "09/17/2015 04:22:00 PM", "09/17/2015 11:01:00 AM", "09/17/2015 08:11:00 PM", "09/17/2015 03:00:00 PM", "09/17/2015 12:43:00 AM", "09/17/2015 12:09:00 PM", "09/17/2015 04:57:00 PM", "09/17/2015 12:25:00 PM", "09/17/2015 06:52:00 AM", "09/17/2015 11:08:00 AM", "09/17/2015 10:25:00 AM", "09/17/2015 02:39:00 PM", "09/17/2015 10:28:00 AM", "09/17/2015 06:39:00 AM", "09/17/2015 09:41:00 AM", "09/17/2015 09:12:00 AM", "09/17/2015 12:40:00 AM", "09/17/2015 11:53:08 AM", "09/17/2015 04:40:30 PM", "09/17/2015 04:19:44 PM", "09/17/2015 08:26:00 AM", "09/17/2015 02:32:17 PM", "09/17/2015 06:09:00 PM", "09/17/2015 10:27:00 AM", "09/17/2015 12:59:00 PM", "09/17/2015 09:20:00 AM", "09/17/2015 07:25:00 AM", "09/17/2015 05:49:04 AM", "09/17/2015 04:58:18 PM", "09/17/2015 11:35:00 AM", "09/17/2015 10:21:48 AM", "09/17/2015 09:48:41 AM", "09/17/2015 01:11:00 PM", "09/17/2015 08:52:00 AM", "09/17/2015 05:49:00 AM", "09/17/2015 06:19:00 PM", "09/17/2015 10:17:19 AM", "09/17/2015 01:59:00 PM", "09/17/2015 11:08:00 AM", "09/17/2015 03:37:59 AM", "09/16/2015 07:00:00 AM", "09/17/2015 02:26:00 PM", "09/17/2015 10:58:00 AM", "09/17/2015 05:56:00 AM", "09/17/2015 05:01:00 PM", "09/17/2015 10:15:00 AM", "09/17/2015 10:02:00 AM", "09/17/2015 10:10:00 PM", "09/17/2015 12:56:00 PM", "09/17/2015 03:58:00 PM", "09/17/2015 05:23:00 PM", "09/17/2015 12:20:00 PM", "09/17/2015 07:48:00 PM", "09/17/2015 02:54:00 PM", "09/17/2015 10:02:00 PM", "09/17/2015 11:53:21 AM", "09/17/2015 10:15:59 AM", "09/17/2015 08:22:00 AM", "09/17/2015 04:33:00 PM", "09/17/2015 08:26:00 PM", "09/17/2015 08:01:00 AM", "09/17/2015 12:28:00 PM", "09/17/2015 11:07:00 PM", "09/17/2015 11:09:00 PM", "09/17/2015 03:08:32 PM", "09/17/2015 08:25:00 PM", "09/17/2015 01:45:00 PM", "09/17/2015 08:42:00 AM", "09/17/2015 03:25:00 PM", "09/17/2015 09:32:00 AM", "09/17/2015 10:13:13 AM", "09/17/2015 11:36:02 AM", "09/17/2015 03:23:00 PM", "09/17/2015 12:00:00 AM", "09/17/2015 07:19:19 PM", "09/17/2015 08:59:06 AM", "09/17/2015 09:14:00 PM", "09/17/2015 01:16:00 PM", "09/17/2015 08:54:35 AM", "09/17/2015 05:56:29 PM", "09/17/2015 03:56:51 PM", "09/17/2015 09:52:22 AM", "09/17/2015 03:49:28 PM", "09/17/2015 01:00:27 PM", "09/17/2015 09:52:32 PM", "09/17/2015 11:08:15 AM", "09/17/2015 05:26:26 PM", "09/17/2015 04:53:56 PM", "09/02/2015 10:33:00 AM", "09/17/2015 10:13:22 AM", "09/17/2015 12:50:00 PM", "09/17/2015 12:46:00 PM", "09/02/2015 06:44:00 PM", "09/17/2015 02:21:06 PM", "09/17/2015 01:56:00 PM", "09/17/2015 02:10:00 PM", "09/17/2015 05:43:28 AM", "09/17/2015 11:24:00 AM", "09/17/2015 10:56:00 AM") ## dput(as.character(parse_date_time2(raw, "mdYHMSp"))) utc <- c("2015-09-17 14:55:00", "2015-09-17 16:22:00", "2015-09-17 11:01:00", "2015-09-17 20:11:00", "2015-09-17 15:00:00", "2015-09-17 00:43:00", "2015-09-17 12:09:00", "2015-09-17 16:57:00", "2015-09-17 12:25:00", "2015-09-17 06:52:00", "2015-09-17 11:08:00", "2015-09-17 10:25:00", "2015-09-17 14:39:00", "2015-09-17 10:28:00", "2015-09-17 06:39:00", "2015-09-17 09:41:00", "2015-09-17 09:12:00", "2015-09-17 00:40:00", "2015-09-17 11:53:08", "2015-09-17 16:40:30", "2015-09-17 16:19:44", "2015-09-17 08:26:00", "2015-09-17 14:32:17", "2015-09-17 18:09:00", "2015-09-17 10:27:00", "2015-09-17 12:59:00", "2015-09-17 09:20:00", "2015-09-17 07:25:00", "2015-09-17 05:49:04", "2015-09-17 16:58:18", "2015-09-17 11:35:00", "2015-09-17 10:21:48", "2015-09-17 09:48:41", "2015-09-17 13:11:00", "2015-09-17 08:52:00", "2015-09-17 05:49:00", "2015-09-17 18:19:00", "2015-09-17 10:17:19", "2015-09-17 13:59:00", "2015-09-17 11:08:00", "2015-09-17 03:37:59", "2015-09-16 07:00:00", "2015-09-17 14:26:00", "2015-09-17 10:58:00", "2015-09-17 05:56:00", "2015-09-17 17:01:00", "2015-09-17 10:15:00", "2015-09-17 10:02:00", "2015-09-17 22:10:00", "2015-09-17 12:56:00", "2015-09-17 15:58:00", "2015-09-17 17:23:00", "2015-09-17 12:20:00", "2015-09-17 19:48:00", "2015-09-17 14:54:00", "2015-09-17 22:02:00", "2015-09-17 11:53:21", "2015-09-17 10:15:59", "2015-09-17 08:22:00", "2015-09-17 16:33:00", "2015-09-17 20:26:00", "2015-09-17 08:01:00", "2015-09-17 12:28:00", "2015-09-17 23:07:00", "2015-09-17 23:09:00", "2015-09-17 15:08:32", "2015-09-17 20:25:00", "2015-09-17 13:45:00", "2015-09-17 08:42:00", "2015-09-17 15:25:00", "2015-09-17 09:32:00", "2015-09-17 10:13:13", "2015-09-17 11:36:02", "2015-09-17 15:23:00", "2015-09-17 00:00:00", "2015-09-17 19:19:19", "2015-09-17 08:59:06", "2015-09-17 21:14:00", "2015-09-17 13:16:00", "2015-09-17 08:54:35", "2015-09-17 17:56:29", "2015-09-17 15:56:51", "2015-09-17 09:52:22", "2015-09-17 15:49:28", "2015-09-17 13:00:27", "2015-09-17 21:52:32", "2015-09-17 11:08:15", "2015-09-17 17:26:26", "2015-09-17 16:53:56", "2015-09-02 10:33:00", "2015-09-17 10:13:22", "2015-09-17 12:50:00", "2015-09-17 12:46:00", "2015-09-02 18:44:00", "2015-09-17 14:21:06", "2015-09-17 13:56:00", "2015-09-17 14:10:00", "2015-09-17 05:43:28", "2015-09-17 11:24:00", "2015-09-17 10:56:00") tparse <- as.POSIXct(utc, tz = "UTC") ## DT(raw, tparse, R = parse_date_time(raw, "mdYT", locale = "C"))[, diff := R - tparse][diff != 0] %>% DF expect_equal(mdy_hms(raw), tparse) expect_equal(parse_date_time2(raw, "mdYHMSp"), tparse) expect_equal(parse_date_time2(raw, "mdYHMSp"), tparse) expect_equal(parse_date_time2(raw, "OmdYHMSOp"), tparse) ## this one ends in strptime expect_equal(parse_date_time(raw, "mdYT", locale = "C"), tparse) }) test_that("heterogeneous formats are correctly parsed", { X <- c(20090101, "2009-01-02", "2009 01 03", "2009-1-4", "2009-1, 5", "2009....1--6", "200901-07", "200901-8") Y <- c("2009-01-01", "2009-01-02", "2009-01-03", "2009-01-04", "2009-01-05", "2009-01-06", "2009-01-07", "2009-01-08") expect_that(ymd(X), equals(as.Date(Y))) ## cbind(ymd(X), as.POSIXct(Y, tz = "UTC")) X <- c(20100101120101, "2009-01-02 12-01-02", "2009.01.03 12:01:03", "2009-1-4 12-1-4", "2009-1, 5 12:1, 5", "2009....1--6 - 12::1:6", "20090107 120107", "2009-01-08 1201-08", "2010-01-09 12:01:09", "2010-01-10 10:01:10 AM", "2010-01-11 10:01:11 PM") Y <- c("2010-01-01 12:01:01", "2009-01-02 12:01:02", "2009-01-03 12:01:03", "2009-01-04 12:01:04", "2009-01-05 12:01:05", "2009-01-06 12:01:06", "2009-01-07 12:01:07", "2009-01-08 12:01:08", "2010-01-09 12:01:09", "2010-01-10 10:01:10", "2010-01-11 22:01:11") ## cbind(as.character(ymd_hms(X)), as.character(as.POSIXct(Y, tz = "UTC"))) expect_that(ymd_hms(X), equals(as.POSIXct(Y, tz = "UTC"))) }) test_that("truncated formats are correctly parsed", { x <- c("2011-12-31 12:59:59", "2010-01-01 12:11", "2010-01-01 12", "2010-01-01") expect_that({ ymd_hms(x, truncated = 3) }, equals(as.POSIXct(c("2011-12-31 12:59:59", "2010-01-01 12:11:00", "2010-01-01 12:00:00", "2010-01-01 00:00:00"), tz = "UTC"))) x <- c("2011-12-31 12", "2010-01-01 12", "2010-01-01 12") expect_equal(ymd_h(x), as.POSIXct(c("2011-12-31 12:00:00 UTC", "2010-01-01 12:00:00 UTC", "2010-01-01 12:00:00 UTC"), tz = "UTC")) x <- c("2011-12-31 12:01", "2010-01-01 12:02", "2010-01-01 12:03") expect_equal(ymd_hm(x), as.POSIXct(c("2011-12-31 12:01:00 UTC", "2010-01-01 12:02:00 UTC", "2010-01-01 12:03:00 UTC"), tz = "UTC")) expect_equal(dmy_h("05-07-2011 13"), ymd_hms("2011-07-05 13:00:00")) expect_equal(ymd_h("2011-07-05 13"), ymd_hms("2011-07-05 13:00:00")) expect_equal(dmy_hm("05-07-2011 13:02"), ymd_hms("2011-07-05 13:02:00")) expect_equal(ymd_hm("2011-07-05 13:02"), ymd_hms("2011-07-05 13:02:00")) }) test_that("truncation on non-dates results in NAs indeed", { expect_warning( expect_true({ tt <- c("NI PODATKA", "TUJINA", "GRAD") all(is.na(ymd_hms(tt, truncated = 3))) })) }) test_that("missing months and days are allowed", { expect_equal(parse_date_time2("2016", orders = "Y"), ymd("2016-01-01", tz = "UTC")) expect_equal(parse_date_time2("2016-02", orders = "Ym"), ymd("2016-02-01", tz = "UTC")) expect_equal(parse_date_time("2016", orders = "Y"), ymd("2016-01-01", tz = "UTC")) expect_equal(parse_date_time("2016-02", orders = "Ym"), ymd("2016-02-01", tz = "UTC")) expect_equal(parse_date_time(c("3:15:00"), c("IMS")), as.POSIXct("00-01-01 03:15:00", tz = "UTC")) expect_equal(parse_date_time(c("3:15:00"), c("HMS")), as.POSIXct("00-01-01 03:15:00", tz = "UTC")) expect_equal(parse_date_time(c("3:15:00 PM"), c("HMSp")), as.POSIXct("00-01-01 15:15:00", tz = "UTC")) expect_equal(parse_date_time(c("3:15:00 PM"), c("IMSp")), as.POSIXct("00-01-01 15:15:00", tz = "UTC")) }) test_that("fractional formats are correctly parsed", { expect_that({ x <- c("2011-12-31 12:59:59.23", "2010-01-01 12:11:10") ymd_hms(x) }, equals(as.POSIXct(c("2011-12-31 12:59:59.23 UTC", "2010-01-01 12:11:10.00 UTC"), tz = "UTC"))) expect_that(hms("3:0:3.34"), equals(hours(3) + minutes(0) + seconds(3.34))) }) test_that("NA's are parsed as NA's", { expect_silent(ymd(NA, "2001-01-01")) expect_warning(ymd(NA, "2001-01-01 01")) expect_true(is.na(ymd(NA, quiet = TRUE))) expect_silent(ymd_hms(NA)) expect_true(is.na(ymd_hms(NA, quiet = TRUE))) expect_silent(ymd_hm(NA, "01-01-01 0:0")) expect_warning(ymd_hm(NA, "01-01-01 0")) expect_true(is.na(ymd_hm(NA, quiet = TRUE))) expect_warning(hms(NA)) expect_true(is.na(hms(NA, quiet = TRUE))) expect_warning(ms(NA)) expect_true(is.na(ms(NA, quiet = TRUE))) }) test_that("Quarters are parsed correctly", { qs <- c("2016.1", "2016:2", "2016-3", "2016 4", "2016.5") out <- ymd(c("2016-01-01 UTC", "2016-04-01 UTC", "2016-07-01 UTC", "2016-10-01 UTC", NA), tz = "UTC") expect_equal(parse_date_time2(qs, orders = "Yq"), out) expect_equal(parse_date_time(qs, orders = "Yq", quiet = T), out) expect_equal(yq(qs, tz = "UTC", quiet = T), out) expect_equal(yq("16.1", "17.3", "2016.1"), ymd(c("2016-01-01", "2017-07-01", "2016-01-01"))) }) test_that("Vectors of NA's are parsed as vectors of NA's", { mna <- as.POSIXct(as.POSIXlt(c(NA, NA, NA), tz = "UTC")) pna <- new("Period" , .Data = c(NA_real_, NA_real_, NA_real_) , year = c(0, 0, 0) , month = c(0, 0, 0) , day = c(0, 0, 0) , hour = c(NA_real_, NA_real_, NA_real_) , minute = c(NA_real_, NA_real_, NA_real_) ) pna2 <- new("Period" , .Data = c(NA_real_, NA_real_, NA_real_) , year = c(0, 0, 0) , month = c(0, 0, 0) , day = c(0, 0, 0) , hour = c(0, 0, 0) , minute = c(NA_real_, NA_real_, NA_real_) ) expect_silent(ymd(NA, NA, NA)) expect_equal(ymd(NA, NA, NA, quiet = TRUE), as.Date(mna)) expect_silent(ymd_hms(NA, NA, NA)) expect_equal(ymd_hms(NA, NA, NA, quiet = TRUE), mna) expect_silent(ymd_hm(NA, NA, NA)) expect_equal(ymd_hm(NA, NA, NA, quiet = TRUE), mna) expect_warning(hms(NA, NA, NA)) expect_equal(hms(NA, NA, NA, quiet = TRUE), pna) expect_warning(ms(NA, NA, NA)) expect_equal(ms(NA, NA, NA, quiet = TRUE), pna2) expect_silent(ymd(c(NA, NA, NA))) expect_equal(ymd(c(NA, NA, NA), quiet = TRUE), as.Date(mna)) expect_silent(ymd_hms(c(NA, NA, NA))) expect_equal(ymd_hms(c(NA, NA, NA), quiet = TRUE), mna) expect_silent(ymd_hm(c(NA, NA, NA))) expect_equal(ymd_hm(c(NA, NA, NA), quiet = TRUE), mna) expect_warning(hms(c(NA, NA, NA))) expect_equal(hms(c(NA, NA, NA), quiet = TRUE), pna) expect_warning(ms(c(NA, NA, NA))) expect_equal(ms(c(NA, NA, NA), quiet = TRUE), pna2) }) test_that("ISO8601: %z format (aka lubridate %Ou, %OO and %Oo formats) is correctly parsed", { expect_that( parse_date_time("2012-12-04 15:06:06.95-0800", "YmdHMOSz"), equals(as.POSIXct("2012-12-04 23:06:06.95 UTC", tz = "UTC"))) expect_that( parse_date_time(c("2012-12-04 15:06:06.95-08", "2012-12-04 15:06:06.95+08:00"), "YmdHMOSz"), equals(as.POSIXct(c("2012-12-04 23:06:06.95 UTC", "2012-12-04 07:06:06.95 UTC"), tz = "UTC"))) expect_that( fast_strptime("2014-03-12T09:32:44Z", "%Y-%m-%dT%H:%M:%S%z"), equals(as.POSIXct("2014-03-12 09:32:44 UTC", tz = "UTC"))) expect_that( fast_strptime("2014-03-12T09:32:44.33Z", "%Y-%m-%dT%H:%M:%OS%z"), equals(as.POSIXct("2014-03-12 09:32:44.33 UTC", tz = "UTC"))) }) test_that("ISO8601: xxx_hms functions work correctly with z, Ou, OO and Oo formats.", { expect_that( ymd_hms(c("2013-01-24 19:39:07.880-0600", "2013-01-24 19:39:07.880", "2013-01-24 19:39:07.880-06:00", "2013-01-24 19:39:07.880-06", "2013-01-24 19:39:07.880Z")), equals(as.POSIXct(c("2013-01-25 01:39:07.88 UTC", "2013-01-24 19:39:07.88 UTC", "2013-01-25 01:39:07.88 UTC", "2013-01-25 01:39:07.88 UTC", "2013-01-24 19:39:07.88 UTC"), tz = "UTC"))) }) test_that("ymd_hms treats time zones correctly", { expect_that(ymd_hms("2012-03-03 23:06:07", tz = "America/Chicago"), equals(as.POSIXct("2012-03-03 23:06:07", tz = "America/Chicago"))) }) test_that("ymd_hms parses Ou format correctly ", { ## Correct usage expect_that(ymd_hms("2012-03-04T05:06:07Z"), equals(ymd_hms("2012-03-04 05:06:07", tz = "UTC"))) expect_that(ymd_hms("2012-03-04T05:06:07Z", tz = "America/Chicago"), equals(ymd_hms("2012-03-03 23:06:07", tz = "America/Chicago"))) ## check for message expect_that(ymd_hms("2012-03-04T05:06:07Z", tz = "America/Chicago"), shows_message("Date in ISO8601 format")) }) test_that("ymd_hms parses OO and Oo formats correctly", { ## +00:00 expect_that(ymd_hms("2012-03-04T05:06:07+00:00"), equals(ymd_hms("2012-03-04 05:06:07", tz = "UTC"))) ## -HH expect_that(ymd_hms("2012-03-04T05:06:07-01"), equals(ymd_hms("2012-03-04 06:06:07", tz = "UTC"))) ## -HHMM expect_that(ymd_hms("2012-03-04T05:06:07-0130"), equals(ymd_hms("2012-03-04 06:36:07", tz = "UTC"))) ## -HH:MM expect_that(ymd_hms("2012-03-04T05:06:07-01:30"), equals(ymd_hms("2012-03-04 06:36:07", tz = "UTC"))) ## +HH expect_that(ymd_hms("2012-03-04T05:06:07+01"), equals(ymd_hms("2012-03-04 04:06:07", tz = "UTC"))) ## +HHMM expect_that(ymd_hms("2012-03-04T05:06:07+0130"), equals(ymd_hms("2012-03-04 03:36:07", tz = "UTC"))) ## +HH:MM expect_that(ymd_hms("2012-03-04T05:06:07+01:30"), equals(ymd_hms("2012-03-04 03:36:07", tz = "UTC"))) ## vectorizes expect_that(ymd_hms(c("2012-03-04T05:06:07+01", "2012-03-04T05:06:07+01:30")), equals(ymd_hms(c("2012-03-04 04:06:07", "2012-03-04 03:36:07"), tz = "UTC"))) expect_that(ymd_hms("2012-03-04T05:06:07-01:30", tz = "America/Chicago", quiet = T), equals(ymd_hms("2012-03-04 00:36:07", tz = "America/Chicago"))) expect_that(ymd_hms("2012-03-04T05:06:07-01:30", tz = "America/Chicago"), shows_message("Date in ISO8601 format")) }) test_that("ymd parses mixed y an Y formats", { ## https://github.com/hadley/lubridate/issues/425 d3 <- c("6/25/15", "6/25/2015") expect_equal(mdy(d3), as.Date(c("2015-06-25", "2015-06-25"))) d6 <- c("25/6/15", "25/6/2015") expect_equal(dmy(d6), as.Date(c("2015-06-25", "2015-06-25"))) d9 <- c("15/6/25", "2015/6/25") expect_equal(ymd(d9), as.Date(c("2015-06-25", "2015-06-25"))) }) test_that("ymd_hms parses mixed ISO-8601/non-ISO-8601 formats", { expect_that(ymd_hms(c("2012-03-04T05:06:07Z", "2001-02-03 04:05:06"), tz = "America/Chicago"), equals(ymd_hms(c("2012-03-03 23:06:07", "2001-02-03 04:05:06"), tz = "America/Chicago"))) }) test_that("parse_date_time2 and fast_strptime parse ISO8601 timezones", { tm <- "2001-02-03 11:22:33-0630" ptm <- as.POSIXct("2001-02-03 17:52:33", tz = "UTC") expect_equal(fast_strptime(tm, "%Y-%m-%d %H:%M:%S%Oz"), ptm) expect_equal(fast_strptime(tm, "%Y-%m-%d %H:%M:%S%z"), ptm) expect_equal(fast_strptime(tm, "%Y-%m-%d %H:%M:%OS%Oz"), ptm) expect_equal(fast_strptime(tm, "%Y-%m-%d %H:%M:%OS%z"), ptm) expect_equal(parse_date_time2(tm, "YmdHMSz"), ptm) expect_equal(parse_date_time2(tm, "YmdHMSOz"), ptm) expect_equal(parse_date_time2(tm, "YmdHMOSz"), ptm) expect_equal(parse_date_time2(tm, "YmdHMOSOz"), ptm) tm <- "2001-02-03 11:22:33-06:30" expect_equal(fast_strptime(tm, "%Y-%m-%d %H:%M:%OS%OO"), ptm) expect_equal(fast_strptime(tm, "%Y-%m-%d %H:%M:%OS%z"), ptm) expect_equal(parse_date_time2(tm, "YmdHMSz"), ptm) expect_equal(parse_date_time2(tm, "YmdHMSOO"), ptm) }) test_that("parse_date_time2 and fast_strptime correctly work with timezones", { ## https://github.com/hadley/lubridate/issues/394 expect_equal(parse_date_time("12/03/16 12:00", "dmy HM", tz = "Europe/Zurich"), parse_date_time2("12/03/16 12:00", "dmy HM", tz = "Europe/Zurich")) expect_equal(as.POSIXct(strptime("12/03/16 12:00", "%d/%m/%y %H:%M", tz = "Europe/Zurich")), parse_date_time2("12/03/16 12:00", "dmy HM", tz = "Europe/Zurich")) expect_equal(strptime("12/03/16 12:00", "%d/%m/%y %H:%M", tz = "Europe/Zurich"), fast_strptime("12/03/16 12:00", "%d/%m/%y %H:%M", tz = "Europe/Zurich")) expect_equal(strptime("12/03/16 12:00", "%d/%m/%y %H:%M", tz = "America/New_York"), fast_strptime("12/03/16 12:00", "%d/%m/%y %H:%M", tz = "America/New_York")) }) test_that("parse_date_time2 and fast_strptime correctly return lt objects", { expect_is(parse_date_time2("12/03/16 12:00", "dmy HM"), "POSIXct") expect_is(parse_date_time2("12/03/16 12:00", "dmy HM", lt = TRUE), "POSIXlt") expect_is(fast_strptime("12/03/16 12:00", "%d/%m/%y %H:%M"), "POSIXlt") expect_is(fast_strptime("12/03/16 12:00", "%d/%m/%y %H:%M", lt = FALSE), "POSIXct") }) test_that("ymd_hms, parse_date_time2, fast_strptime and base:strptime give the same result", { ## random times between 1400 and 3000 set.seed(1000) X <- as.character(.POSIXct(runif(1000, -17987443200, 32503680000))) oposix <- as.POSIXct(X, tz = "UTC") opdt1 <- ymd_hms(X) opdt2 <- parse_date_time2(X, "YmdHMOS") ofstrptime <- fast_strptime(X, "%Y-%m-%d %H:%M:%OS") expect_equal(oposix, opdt1) expect_equal(oposix, opdt2) expect_equal(oposix, ofstrptime) tzs <- strptime(X, "%Y-%m-%d %H:%M:%OS", tz = "America/New_York") tzfs <- fast_strptime(X, "%Y-%m-%d %H:%M:%OS", tz = "America/New_York") expect_equal(tzs, tzfs) }) test_that("fast_strptime and parse_date_time2 parse correctly verbose formats", { expect_equal(fast_strptime("aa 2000 bbb10ccc 12 zzz", "aa %Y bbb%mccc %d zzz"), as.POSIXct("2000-10-12", tz = "UTC")) expect_equal(fast_strptime("aa 2000 5555 bbb10ccc 12 zzz", "aa %Y 5555 bbb%mccc %d zzz"), as.POSIXct("2000-10-12", tz = "UTC")) expect_equal(parse_date_time2("aa 2000 bbb10ccc 12 zzz", "Ymd"), as.POSIXct("2000-10-12", tz = "UTC")) expect_equal(parse_date_time2("aa 2000 5555 bbb10ccc 12 zzz", "Ymd"), as.POSIXct(as.POSIXlt(NA, tz = "UTC"))) }) test_that("fast_strptime and parse_date_time2 deal correctly with leap years", { expect_equal(ymd(c("2000-02-29", "2100-02-29", "2400-02-29"), quiet = T), as.Date(c("2000-02-29 UTC", NA, "2400-02-29 UTC"))) }) test_that("fast_strptime and parse_date_time2 detect excesive days", { ## https://github.com/hadley/lubridate/issues/#289 expect_equal(ymd(c("2000-01-32", "2000-02-30", "2100-03-32", "2400-12-32"), quiet = T), as.Date(c(NA, NA, NA, NA)), tz = "UTC") }) test_that("fast_strptime and parse_date_time2 aggree with strptime", { date <- "1 7 97" expect_equal(fast_strptime(date, "%d %m %y"), strptime(date, "%d %m %y", tz = "UTC")) date <- "1 1 69" expect_equal(fast_strptime(date, "%d %m %y"), strptime(date, "%d %m %y", tz = "UTC")) date <- "1 1 68" expect_equal(fast_strptime(date, "%d %m %y"), strptime(date, "%d %m %y", tz = "UTC")) expect_equal(parse_date_time2(date, "dmy"), strptime(date, "%d %m %y", tz = "UTC")) }) test_that("a and A formats are handled correctly (#254)", { dates <- c("Saturday 31 August 2013", "Sun 12 Jan 2014") expect_equal(parse_date_time(x = dates, orders = c("dby")), parse_date_time(x = dates, orders = c("adby"))) expect_equal(parse_date_time(x = dates, orders = c("dby")), parse_date_time(x = dates, orders = c("Adby"))) }) test_that("`parse_date_time` parses heterogeneous formats with `exact=TRUE`", { ## https://github.com/hadley/lubridate/issues/326 expect_equal(parse_date_time(c("12/17/1996 04:00:00", "4/18/1950 0130"), c("%m/%d/%Y %I:%M:%S", "%m/%d/%Y %H%M"), exact = T), as.POSIXct(c("1996-12-17 04:00:00 UTC", "1950-04-18 01:30:00 UTC"), tz = "UTC")) x <- c("09-01-01", "090102", "09-01 03", "09-01-03 12:02") expect_equal(parse_date_time(x, c("%m-%d-%y", "%m%d%y", "%m-%d-%y %H:%M"), exact = TRUE, quiet = T), as.POSIXct(c("2001-09-01 00:00:00 UTC", "2002-09-01 00:00:00 UTC", NA, "2003-09-01 12:02:00 UTC"), tz = "UTC")) }) test_that("parser ignores case", { ref <- ymd_hms("2016-01-04 07:40:00", "2016-01-04 07:40:00", "2016-01-04 07:40:00 UTC") dts <- c("04jan2016:07:40:00", "04JAN2016:07:40:00", "04Jan2016:07:40:00") expect_equal(ref, parse_date_time2(dts, "dBYHMS")) expect_equal(ref, dmy_hms(dts)) }) ## library(microbenchmark) ## library(lubridate) ### PARSING ## options(digits.secs = 3) ## set.seed(100) ## tt <- as.character(.POSIXct(runif(1e6, -17987443200, 32503680000))) # random times between 1400 and 3000 ## microbenchmark(#POSIXct = as.POSIXct(tt, tz = "UTC"), ## ymd_hms = ymd_hms(tt), ## pdt2 = parse_date_time2(tt, "YmdHMOS"), ## fstrptime = fast_strptime(tt, "%Y-%m-%d %H:%M:%OS", lt = FALSE), ## readr = parse_datetime(tt, "%Y-%m-%d %H:%M:%OS"), ## times = 10) ### MAKE DATETIMES ## N <- 1e4 ## y <- as.integer(runif(N, 1800, 2200)) ## m <- as.integer(runif(N, 1, 12)) ## d <- as.integer(runif(N, 1, 28)) ## H <- as.integer(runif(N, 0, 23)) ## M <- as.integer(runif(N, 0, 59)) ## S <- as.double(runif(N, 0, 59)) ## ## S <- as.integer(S) ## microbenchmark(R = ISOdatetime(y, m, d, H, M, S, tz = "UTC"), ## L = make_datetime(y, m, d, H, M, S)) ## system.time(out1 <- ISOdatetime(y, m, d, H, M, S, tz = "UTC")) ## system.time(out2 <- make_datetime(y, m, d, H, M, S)) ## all.equal(out1, out2) ## table(out1 == out2) ## tt <- cbind(y, m, d, H, M, S, as.character(out1), as.character(out2), out1 == out2) ## tt <- cbind(y, m, d, H, M, S, out1, out2, out1 - out2, out1 == out2) ## head(tt, 40) ## cbind(out1, out2)[which(out1 != out2), ] ## all.equal(out, out1) ## all.equal(out, out2) ## all.equal(out, out3) ## this one is very slow ## system.time(out <- ymd_hms(tt, tz = "America/Chicago")) ## ttz <- paste(tt, "-0600", sep = "") ## system.time(out <- parse_date_time(ttz, "YmdHMOSz")) ## system.time(out <- ymd_hms(ttz)) ## head(ttz) ## head(out) ## system.time(out2 <- parse_date_time2(ttz, "YmdHMOSz")) ## system.time(out2 <- parse_date_time2(ttz, "YmdHMOSOz")) ## system.time(out3 <- fast_strptime(ttz, "%Y-%m-%d %H:%M:%OS%z")) ## all.equal(out, out2) ## all.equal(out, out3) ## fast_strptime(tm, "%Y-%m-%d %H:%M:%S%z") ## fast_strptime("2893-04-08 22:54:37+0635", "%Y-%m-%d %H:%M:%S%Oz") ## system.time(out <- ymd_hms(ttz, tz = "")) ## stamp_OO <- stamp("2013-01-01T00:00:00-06:00") ## stamp_Ou <- stamp("2013-01-01T06:00:00Z") ## stamp_Oo <- stamp("2013-01-01T00:00:00-06") ## stamp_Oz <- stamp("2013-01-01T00:00:00-0600") ## stamp_OO <- stamp("2013-01-01T00:00:00-06:00") ## stamp_simple <- stamp("2013-01-01T00:00:00") ## system.time(out_st <- stamp_simple(out)) ## system.time(out_st <- stamp_Ou(out)) ## system.time(out_st <- stamp_OO(out)) ## system.time(out_st <- stamp_OO(out)) ## system.time(out_st <- stamp_Oz(out)) ## tt <- rep(c(as.character(Sys.time()), as.character(Sys.Date())), 5e5) ## system.time(out <- as.POSIXct(tt, tz = "UTC")) ## system.time(out <- ymd_hms(tt, tz = "UTC", truncated = 3)) ## Rprof() ## system.time(out <- as.POSIXct(strptime(tt, "%Y-%m-%d %H:%M:%S", tz = "UTC"))) ## Rprof(NULL) ## Rprof() ## system.time(out <- ymd_hms(tt)) ## Rprof(NULL) ## summaryRprof() lubridate/tests/testthat/test-guess.R0000644000176200001440000000503013201152061017442 0ustar liggesusers## This is for interactive tests mainly, (test-parser.R and test-stamp.R are ussing gueesser, so it should be enough) ## x <- c('February 20th 1973', ## "february 14, 2004", ## "Sunday, May 1, 2000", ## "Sunday, May 1, 2000", ## "february 14, 04", ## 'Feb 20th 73', ## "January 5 1999 at 7 pm", ## "January 5 1999 at7pm", ## "jan 3 2010", ## "Jan 1, 1999", ## "jan 3 10", ## "01 3 2010", ## "1 3 10", ## '1 13 89', ## "5/27/1979", ## "12/31/99", ## "DOB:12/11/00", ## "-----------", ## 'Thu, 1 July 2004 22:30:00', ## 'Thu, 1st of July 2004 at 22:30:00', ## 'Thu, 1July 2004 at 22:30:00', ## 'Thu, 1July2004 22:30:00', ## "21 Aug 2011, 11:15:34 pm", ## "-----------", ## "1979-05-27 05:00:59", ## "1979-05-27", ## "-----------", ## "3 jan 2000", ## "17 april 85", ## "27/5/1979", ## '20 01 89', ## '00/13/10', ## "-------", ## "14 12 00", ## "03:23:22 pm") ## guess_formats(x, "BdY", print = T) ## guess_formats(x, "Bdy") ## guess_formats(x, "bdY") ## guess_formats(x, "bdy") ## guess_formats(x, "mdy", print = T) ## guess_formats(x, "T", print = T) ## guess_formats(x, c("mdY", "BdY", "Bdy", "bdY", "bdy")) ## guess_formats(x, c("dby", "dbY", "dBy", "dBY")) ## guess_formats(x, c("mdY", "mdy")) ## guess_formats(x, c("dmY", "dmy")) ## guess_formats(x, c("BdY H", "dBY HMS", "dbY HMS")) ## guess_formats(x, c("dBy HMS")) ## guess_formats(x, c("Ymd HMS"), print_matches=T) ## guess_formats(x, c("dmy HMS"), print_matches=T) ## guess_formats(x, c("mdY r"), print_matches=T) ## stamp(x, c("BdY", "bdY", "bd"))(Sys.time()) ## system.time(stamp(x[1], "BdY", quiet = T)) ## stamp(x, quiet = F) ## y <- rep(x, 3) ## f <- rep(c("BdY", "bdY", "bdy"), 10) ## system.time( for (i in 1:1) substitute_formats(y, f)) ## reg <- c("\\b(?[0-2]?\\d)\\D*?(?

(AM|PM))", ## "\\b(?[0-2]?\\d)\\D*?(?(DD|BB))") ## reg <- c("\\b((?(?[0-2]?\\d)\\D*?(?(AM|PM)))|(?(?[0-2]?\\d)\\D*?(?

(DD|BB))))") ## x <- c("aaa 12 DD aaa", ## "bbb 22 AM bbb", ## "ccc 14 PM ccc") ## ## gsub(reg , "####",x , ignore.case=T, perl = TRUE) ## regexpr(reg[[1]], x, perl=T) context("Guessing format") test_that(".get_train_set can find non NA dates", { x <- suppressWarnings(suppressMessages(ymd(c(rep(NA, 199), 20130213)))) expect_equal(x, as.Date(as.POSIXct(c(rep(NA, 199), "2013-02-13"), tz = "UTC"))) }) lubridate/tests/testthat/test-namespace.R0000644000176200001440000000352313234630403020264 0ustar liggesuserscontext("Namespace") if (file.exists("../../00check.log")) { # test was invoked by R CMD check -> package is already built R_test_lib <- normalizePath("../..") env <- paste0("R_LIBS=", R_test_lib, ":", Sys.getenv("R_LIBS")) } else { # We're testing in the source directory -> need to build and install R_test_lib <- file.path(tempdir(), "Rlib") env <- "" ## dir.create(R_test_lib) ## on.exit(unlink(R_test_lib, recursive = TRUE)) ## system2( ## "R", ## c("CMD install", ## paste0("--library=", R_test_lib), ## "--no-docs --no-help --no-demo --no-data --no-test-load", ## normalizePath("../..")), ## stdout = TRUE, stderr = TRUE) } do_Rscript <- function(expr) { rscript <- sprintf("%s/bin/Rscript", Sys.getenv("R_HOME")) paste( system2(rscript, args = c("--vanilla", "--default-packages=NULL", "-e", shQuote(expr)), env = c("R_TESTS=", env), stdout = TRUE, stderr = TRUE), collapse = "\n") } test_that("methods is not attached", { skip_on_cran() # Checking test assumptions. # If this fails, namespace tests may not be needed anymore! expect_match( do_Rscript("'package:methods' %in% search()"), "FALSE") }) test_that("lubridate:: calls work when methods is not attached", { skip_on_cran() expect_match( # https://github.com/tidyverse/lubridate/issues/314 do_Rscript( "lubridate::round_date(as.POSIXct('2017-10-03 03:01:13Z'), 'minute')"), as.character(round_date(as.POSIXct('2017-10-03 03:01:13Z'), 'minute')), fixed = TRUE) expect_match( # https://github.com/tidyverse/lubridate/issues/407 do_Rscript("lubridate::days(1)"), as.character(days(1)), fixed = TRUE) expect_match( # https://github.com/tidyverse/lubridate/issues/499 do_Rscript("lubridate::dhours(22)"), as.character(dhours(22)), fixed = TRUE) }) lubridate/tests/testthat/test-ops-compare.R0000644000176200001440000000644713236362333020573 0ustar liggesuserscontext("Comparisons operations") test_that("Comparison operators work with POSIX and Date objects", { expect_true(ymd_hms("2016-01-03 00:00:00", tz = "") == "2016-01-03 00:00:00") expect_true(ymd_hms("2016-01-03 00:00:00", tz = "") == "2016-01-03") expect_true(ymd_hms("2016-01-03 00:00:01", tz = "") > "2016-01-03 00:00:00") expect_true(ymd("2016-01-03") == "2016-01-03") expect_true(ymd("2016-01-03") > "2016-01-02") expect_true(ymd("2016-01-03") < "2016-01-04") expect_true(ymd("2016-01-03") == ymd_hms("2016-01-03 00:00:00")) expect_true(ymd("2016-01-03") < ymd_hms("2016-01-03 00:00:01")) expect_true(ymd("2016-01-03") != ymd_hms("2016-01-03 00:00:01")) expect_true(ymd("2016-01-03") > ymd_hms("2016-01-02 23:59:59")) expect_true(ymd("2016-01-03") > ymd_hms("2016-01-02 23:59:59", tz = "Europe/Paris")) expect_true(ymd("2016-01-03") < ymd_hms("2016-01-03 00:00:01", tz = "Europe/Paris")) expect_true(ymd("2016-01-03") < ymd_hms("2016-01-03 00:00:01", tz = "Europe/Paris")) expect_true(ymd("2016-01-03") < as.POSIXlt(ymd_hms("2016-01-03 00:00:01", tz = "Europe/Paris"))) expect_true(ymd("2016-01-03") < as.POSIXlt(ymd_hms("2016-01-03 00:00:01", tz = "Europe/Paris"))) }) test_that("Duration and periods are comparable", { expect_true(dyears(1) < years(1)) expect_false(dyears(1) > years(1)) }) test_that("character comparison with periods works as expected", { expect_true(period(days = 1) == "day") expect_true(period(days = 2, seconds = 2) == "2 days, 2 secs") expect_true("day" == period(days = 1)) expect_true("2 days, 2 secs" == period(days = 2, seconds = 2)) expect_true(period("day 1s") > period(days = 1)) expect_true("day 1s" > period(days = 1)) expect_true("day 1S 2H" == period(days = 1, seconds = 1, hours = 2)) expect_false("day 1S 2H" < period(days = 1, hours = 2)) expect_true("day 1S 2H 3m 2y" > period(days = 1, months = 3, years = 2, hours = 2)) }) test_that("duration comparison with periods works as expected", { expect_true(period(days = 1) == duration(days = 1)) expect_true(duration(days = 1) == period(days = 1)) expect_true(period(days = 2, seconds = 2) == duration("2 days, 2 secs")) expect_true(duration("day") == period(days = 1)) expect_true(ddays() == days()) expect_true(duration("day 1s") > period(days = 1)) expect_true(duration("day 1s") > period(days = 1)) expect_true(duration("day 1S 2H") == period(days = 1, seconds = 1, hours = 2)) expect_false(duration("day 1S 2H") < period(days = 1, hours = 2)) expect_true(duration("day 1S 2H 3m 2y") > period(days = 1, months = 3, years = 2, hours = 2)) }) test_that("character comparison with durrations works as expected", { expect_true("day" == duration(days = 1)) expect_true("2 days, 2 secs" == duration(days = 2, seconds = 2)) expect_true(duration("day 1s") > duration(days = 1)) expect_true("day 1s" > duration(days = 1)) expect_true("day 1S 2H" == duration(days = 1, seconds = 1, hours = 2)) expect_false("day 1S 2H" < duration(days = 1, hours = 2)) }) test_that("difftime comparison with periods works", { t <- now() expect_true(days(1) == (t + days(1)) - t) expect_true((t + days(1)) - t == days(1)) }) test_that("difftime comparison with durations works", { t <- now() expect_true(ddays(1) == (t + ddays(1)) - t) expect_true((t + ddays(1)) - t == ddays(1)) }) lubridate/tests/testthat/test-am-pm.R0000644000176200001440000000177713201152061017341 0ustar liggesuserscontext("AM/PM") test_that("am and pm correctly identify time of day", { x <- as.POSIXct("2009-08-03 13:01:59", tz = "UTC") y <- as.POSIXct("2008-08-03 10:01:59", tz = "UTC") expect_that(am(x), is_false()) expect_that(am(y), is_true()) expect_that(pm(x), is_true()) expect_that(pm(y), is_false()) }) test_that("am and pm handle vectors", { x <- as.POSIXct(c("2009-08-03 13:01:59", "2008-08-03 10:01:59"), tz = "UTC") y <- as.POSIXct(c("2009-08-03 10:01:59", "2008-08-03 13:01:59"), tz = "UTC") expect_that(pm(x)[1], is_true()) expect_that(pm(x)[2], is_false()) expect_that(am(y)[1], is_true()) expect_that(am(y)[2], is_false()) }) test_that("am and pm handle various classes of date-time object", { x <- as.POSIXct(c("2008-08-03 13:01:59", "2009-08-03 10:01:59"), tz = "UTC") expect_that(pm(x)[1], is_true()) expect_that(pm(x)[2], is_false()) expect_that(pm(as.Date(x))[1], is_false()) expect_that(pm(as.POSIXlt(x))[1], is_true()) expect_that(pm(as.POSIXlt(x))[2], is_false()) }) lubridate/src/0000755000176200001440000000000013263152652013021 5ustar liggesuserslubridate/src/Makevars0000644000176200001440000000102313263152652014511 0ustar liggesusersCXX_STD = CXX11 PKG_CPPFLAGS= -I. -I./cctz/include/ -I./cctz/src/ PKG_LIBS= -L. -lcctz LIBCCTZ=./cctz/src/time_zone_fixed.o \ ./cctz/src/time_zone_if.o \ ./cctz/src/time_zone_impl.o \ ./cctz/src/time_zone_info.o \ ./cctz/src/time_zone_libc.o \ ./cctz/src/time_zone_lookup.o \ ./cctz/src/time_zone_posix.o \ # ./cctz/src/time_zone_format.o \ # ./cctz/src/time_tool.o $(SHLIB): libcctz.a libcctz.a: $(LIBCCTZ) $(AR) rcs libcctz.a $(LIBCCTZ) clean: rm -f $(SHLIB) $(LIBCCTZ) $(OBJECTS) libcctz.a lubridate/src/update.cpp0000644000176200001440000003657713263152652015031 0ustar liggesusers#include #include #include #include "civil_time.h" #include "time_zone.h" #include "utils.h" #include // CIVIL TIME: // https://github.com/google/cctz/blob/master/include/civil_time.h // https://github.com/devjgm/papers/blob/master/d0215r1.md // TIME ZONES: // https://github.com/google/cctz/blob/master/include/time_zone.h // https://github.com/devjgm/papers/blob/master/d0216r1.md // https://raw.githubusercontent.com/devjgm/papers/master/resources/struct-civil_lookup.png // R's timezone registry: // https://github.com/SurajGupta/r-source/blob/master/src/extra/tzone/registryTZ.c /// floor int_fast64_t NA_INT32 = static_cast(NA_INTEGER); int_fast64_t NA_INT64 = std::numeric_limits::min(); double fINT64_MAX = static_cast(std::numeric_limits::max()); double fINT64_MIN = static_cast(std::numeric_limits::min()); int_fast64_t floor_to_int64(double x) { // maybe fixme: no warning yet on integer overflow if (ISNAN(x)) return NA_INT64; x = std::floor(x); if (x > fINT64_MAX || x <= fINT64_MIN) { return NA_INT64; } return static_cast(x); } /// tzone utilities namespace chrono = std::chrono; using sys_seconds = chrono::duration; using time_point = chrono::time_point; const std::unordered_map TZMAP { {"CEST", 2}, {"CET", 1}, {"EDT", -4}, {"EEST", 3}, {"EET", 2}, {"EST", -5}, {"PDT", -7}, {"PST", -8}, {"WEST", 1}, {"WET", 0} }; const char* tz_from_R_tzone(SEXP tz) { if (Rf_isNull(tz)) { return ""; } else { if (!Rf_isString(tz)) Rf_error("'tz' is not a character vector"); const char* tz0 = CHAR(STRING_ELT(tz, 0)); if (strlen(tz0) == 0) { if (LENGTH(tz) > 1) { return CHAR(STRING_ELT(tz, 1)); } } return tz0; } } const char* tz_from_tzone_attr(SEXP x){ return tz_from_R_tzone(Rf_getAttrib(x, Rf_install("tzone"))); } const char* get_current_tz() { // ugly workaround to get local time zone (abbreviation) as seen by R (not used) Rcpp::NumericVector origin = Rcpp::NumericVector::create(0); origin.attr("class") = Rcpp::CharacterVector::create("POSIXct", "POSIXt"); Rcpp::Environment base = Rcpp::Environment::base_namespace(); Rcpp::Function as_posixlt(base["as.POSIXlt.POSIXct"]); return tz_from_R_tzone(as_posixlt(origin)); } const char* get_system_tz() { Rcpp::Environment base = Rcpp::Environment::base_namespace(); Rcpp::Function sys_timezone(base["Sys.timezone"]); SEXP sys_tz = STRING_ELT(sys_timezone(), 0); if (sys_tz == NA_STRING || strlen(CHAR(sys_tz)) == 0) { Rf_warning("System timezone name is unknown. Please set environment variable TZ."); return "UTC"; } else { return CHAR(sys_tz); } } const char* local_tz() { // initialize once per session static const char* SYS_TZ = strdup(get_system_tz()); const char* tz_env = std::getenv("TZ"); if (tz_env == NULL) { return SYS_TZ; } else if (strlen(tz_env) == 0) { // FIXME: // if set but empty, it's system specific ... // Is there a way way to get TZ name as R sees it? Rf_warning("Environment variable TZ is set to \"\". Things might break."); return get_current_tz(); } else { return tz_env; } } bool load_tz(std::string tzstr, cctz::time_zone& tz) { // return `true` if loaded, else false if (tzstr.size() == 0) { // CCTZ doesn't work on windows https://github.com/google/cctz/issues/53 /* std::cout << "Local TZ: " << local_tz() << std::endl; */ return cctz::load_time_zone(local_tz(), &tz); } else { if (!cctz::load_time_zone(tzstr, &tz)) { auto el = TZMAP.find(tzstr); if (el != TZMAP.end()) { tz = cctz::fixed_time_zone(chrono::hours(el->second)); } else { return false; } } return true; } } // [[Rcpp::export]] Rcpp::CharacterVector C_local_tz() { return Rf_mkString(local_tz()); } // [[Rcpp::export]] Rcpp::LogicalVector C_valid_tz(const Rcpp::CharacterVector& tz_name) { cctz::time_zone tz; std::string tzstr(tz_name[0]); return load_tz(tzstr, tz); } void load_tz_or_fail(std::string tzstr, cctz::time_zone& tz, std::string error_msg) { if (!load_tz(tzstr, tz)) { Rcpp::stop(error_msg.c_str(), tzstr); } } // Helper for conversion functions. Get seconds from civil_lookup, but relies on // use original time pre/post time if cl_new falls in repeated interval. double get_secs_from_civil_lookup(const cctz::time_zone::civil_lookup& cl_new, // new lookup const cctz::time_zone& tz_orig, // original time zone const time_point& tp_orig, // original time point const cctz::civil_second& cs_orig, // original time in secs bool roll, double remainder = 0.0) { time_point tp_new; if (cl_new.kind == cctz::time_zone::civil_lookup::UNIQUE) { // UNIQUE tp_new = cl_new.pre; } else if (cl_new.kind == cctz::time_zone::civil_lookup::SKIPPED) { // SKIPPED if (roll) tp_new = cl_new.trans; else { return NA_REAL; } } else { // REPEATED // match pre or post time of original time const cctz::time_zone::civil_lookup cl_old = tz_orig.lookup(cs_orig); if (tp_orig >= cl_old.trans){ tp_new = cl_new.post; } else { tp_new = cl_new.pre; } /* Rcpp::Rcout << cctz::format("tp:%Y-%m-%d %H:%M:%S %z", tp1, tz1) << std::endl; */ /* Rcpp::Rcout << cctz::format("pre:%Y-%m-%d %H:%M:%S %z", cl1.pre, tz1) << std::endl; */ /* Rcpp::Rcout << cctz::format("trans:%Y-%m-%d %H:%M:%S %z", cl1.trans, tz1) << std::endl; */ /* Rcpp::Rcout << cctz::format("post:%Y-%m-%d %H:%M:%S %z", cl1.post, tz1) << std::endl; */ } return tp_new.time_since_epoch().count() + remainder; } // [[Rcpp::export]] Rcpp::newDatetimeVector C_update_dt(const Rcpp::NumericVector& dt, const Rcpp::IntegerVector& year, const Rcpp::IntegerVector& month, const Rcpp::IntegerVector& yday, const Rcpp::IntegerVector& mday, const Rcpp::IntegerVector& wday, const Rcpp::IntegerVector& hour, const Rcpp::IntegerVector& minute, const Rcpp::NumericVector& second, const SEXP tz = R_NilValue, const bool roll = false, const int week_start = 7) { if (dt.size() == 0) return(Rcpp::newDatetimeVector(dt)); std::vector sizes {year.size(), month.size(), yday.size(), mday.size(), wday.size(), hour.size(), minute.size(), second.size()}; // tz is always there, so the output is at least length 1 R_xlen_t N = std::max(*std::max_element(sizes.begin(), sizes.end()), dt.size()); bool do_year = sizes[0] > 0, do_month = sizes[1] > 0, do_yday = sizes[2] > 0, do_mday = sizes[3] > 0, do_wday = sizes[4] > 0, do_hour = sizes[5] > 0, do_minute = sizes[6] > 0, do_second = sizes[7] > 0; bool loop_year = sizes[0] == N, loop_month = sizes[1] == N, loop_yday = sizes[2] == N, loop_mday = sizes[3] == N, loop_wday = sizes[4] == N, loop_hour = sizes[5] == N, loop_minute = sizes[6] == N, loop_second = sizes[7] == N, loop_dt = dt.size() == N; if (sizes[0] > 1 && !loop_year) Rcpp::stop("C_update_dt: Invalid size of 'year' vector"); if (sizes[1] > 1 && !loop_month) Rcpp::stop("C_update_dt: Invalid size of 'month' vector"); if (sizes[2] > 1 && !loop_yday) Rcpp::stop("C_update_dt: Invalid size of 'yday' vector"); if (sizes[3] > 1 && !loop_mday) Rcpp::stop("C_update_dt: Invalid size of 'mday' vector"); if (sizes[4] > 1 && !loop_wday) Rcpp::stop("C_update_dt: Invalid size of 'wday' vector"); if (sizes[5] > 1 && !loop_hour) Rcpp::stop("C_update_dt: Invalid size of 'hour' vector"); if (sizes[6] > 1 && !loop_minute) Rcpp::stop("C_update_dt: Invalid size of 'minute' vector"); if (sizes[7] > 1 && !loop_second) Rcpp::stop("C_update_dt: Invalid size of 'second' vector"); if (dt.size() > 1 && !loop_dt) Rcpp::stop("C_update_dt: length of dt vector must be 1 or match the length of updating vectors"); if (do_yday + do_mday + do_wday > 1) Rcpp::stop("Conflicting days input, only one of yday, mday and wday must be supplied"); std::string tzfrom = tz_from_tzone_attr(dt); cctz::time_zone tzone1; load_tz_or_fail(tzfrom, tzone1, "CCTZ: Invalid timezone of the input vector: \"%s\""); std::string tzto; cctz::time_zone tzone2; if (Rf_isNull(tz)) { tzto = tzfrom; } else { tzto = tz_from_R_tzone(tz); } load_tz_or_fail(tzto, tzone2, "CCTZ: Unrecognized tzone: \"%s\""); Rcpp::NumericVector out(N); // all vectors are either size N or 1 for (R_xlen_t i = 0; i < N; i++) { double dti = loop_dt ? dt[i] : dt[0]; int_fast64_t secs = floor_to_int64(dti); if (ISNAN(dti) || secs == NA_INT64) { out[i] = NA_REAL; continue; } double rem = 0.0; sys_seconds ss(secs); time_point tp1(ss); cctz::civil_second ct1 = cctz::convert(tp1, tzone1); int_fast64_t y = ct1.year(), m = ct1.month(), d = ct1.day(), H = ct1.hour(), M = ct1.minute(), S = ct1.second(); if (do_year) { y = loop_year ? year[i] : year[0]; if (y == NA_INT32) {out[i] = NA_REAL; continue; } } if (do_month) { m = loop_month ? month[i] : month[0]; if (m == NA_INT32) {out[i] = NA_REAL; continue; } } if (do_mday) { d = loop_mday ? mday[i] : mday[0]; if (d == NA_INT32) {out[i] = NA_REAL; continue; } } if (do_hour) { H = loop_hour ? hour[i] : hour[0]; if (H == NA_INT32) {out[i] = NA_REAL; continue; } } if (do_minute) { M = loop_minute ? minute[i] : minute[0]; if (M == NA_INT32) {out[i] = NA_REAL; continue; } } if (do_second) { if (loop_second) { S = floor_to_int64(second[i]); rem = second[i] - S; } else { S = floor_to_int64(second[0]); rem = second[0] - S; } if (S == NA_INT64) {out[i] = NA_REAL; continue; } } if (do_yday) { // yday and d are 1 based d = d - cctz::get_yearday(cctz::civil_day(ct1)); /* if (IS_LEAP(y) && ct1.month() > 2) d -= 1; */ if (loop_yday) d += yday[i]; else d += yday[0]; } if (do_wday) { // wday is 1 based and starts on week_start int cur_wday = (static_cast(cctz::get_weekday(cctz::civil_day(ct1))) + 8 - week_start) % 7; d = d - cur_wday - 1; if (loop_wday) d += wday[i]; else d += wday[0]; } const cctz::civil_second cs2(y, m, d, H, M, S); const cctz::time_zone::civil_lookup cl2 = tzone2.lookup(cs2); out[i] = get_secs_from_civil_lookup(cl2, tzone1, tp1, ct1, roll, rem); } return Rcpp::newDatetimeVector(out, tzto.c_str()); } // [[Rcpp::export]] Rcpp::newDatetimeVector C_force_tz(const Rcpp::NumericVector dt, const Rcpp::CharacterVector tz, const bool roll = false) { // roll: logical, if `true`, and `time` falls into the DST-break, assume the // next valid civil time, otherwise return NA if (tz.size() != 1) Rcpp::stop("`tz` argument must be a single character string"); std::string tzfrom_name = tz_from_tzone_attr(dt); std::string tzto_name(tz[0]); cctz::time_zone tzfrom, tzto; load_tz_or_fail(tzfrom_name, tzfrom, "CCTZ: Unrecognized timezone of the input vector: \"%s\""); load_tz_or_fail(tzto_name, tzto, "CCTZ: Unrecognized output timezone: \"%s\""); /* std::cout << "TZ from:" << tzfrom.name() << std::endl; */ /* std::cout << "TZ to:" << tzto.name() << std::endl; */ size_t n = dt.size(); Rcpp::NumericVector out(n); for (size_t i = 0; i < n; i++) { int_fast64_t secs = floor_to_int64(dt[i]); /* printf("na: %i na64: %+" PRIiFAST64 " secs: %+" PRIiFAST64 " dt: %f\n", NA_INTEGER, INT_FAST64_MIN, secs, dt[i]); */ if (secs == NA_INT64) {out[i] = NA_REAL; continue; } double rem = dt[i] - secs; sys_seconds d1(secs); time_point tp1(d1); cctz::civil_second ct1 = cctz::convert(tp1, tzfrom); const cctz::time_zone::civil_lookup cl2 = tzto.lookup(ct1); out[i] = get_secs_from_civil_lookup(cl2, tzfrom, tp1, ct1, roll, rem); } return Rcpp::newDatetimeVector(out, tzto_name.c_str()); } // [[Rcpp::export]] Rcpp::newDatetimeVector C_force_tzs(const Rcpp::NumericVector dt, const Rcpp::CharacterVector tzs, const Rcpp::CharacterVector tz_out, const bool roll = false) { // roll: logical, if `true`, and `time` falls into the DST-break, assume the // next valid civil time, otherwise return NA if (tz_out.size() != 1) Rcpp::stop("In 'tzout' argument must be of length 1"); if (tzs.size() != dt.size()) Rcpp::stop("In 'C_force_tzs' tzs and dt arguments must be of the same length"); std::string tzfrom_name = tz_from_tzone_attr(dt); std::string tzout_name(tz_out[0]); cctz::time_zone tzfrom, tzto, tzout; load_tz_or_fail(tzfrom_name, tzfrom, "CCTZ: Unrecognized timezone of input vector: \"%s\""); load_tz_or_fail(tzout_name, tzout, "CCTZ: Unrecognized timezone: \"%s\""); std::string tzto_old_name("not-a-tz"); size_t n = dt.size(); Rcpp::NumericVector out(n); for (size_t i = 0; i < n; i++) { std::string tzto_name(tzs[i]); if (tzto_name != tzto_old_name) { load_tz_or_fail(tzto_name, tzto, "CCTZ: Unrecognized timezone: \"%s\""); tzto_old_name = tzto_name; } int_fast64_t secs = floor_to_int64(dt[i]); if (secs == NA_INT64) { out[i] = NA_REAL; continue; } double rem = dt[i] - secs; sys_seconds secsfrom(secs); time_point tpfrom(secsfrom); cctz::civil_second csfrom = cctz::convert(tpfrom, tzfrom); const cctz::time_zone::civil_lookup clto = tzto.lookup(csfrom); out[i] = get_secs_from_civil_lookup(clto, tzfrom, tpfrom, csfrom, roll, rem); } return Rcpp::newDatetimeVector(out, tzout_name.c_str()); } // [[Rcpp::export]] Rcpp::NumericVector C_local_time(const Rcpp::NumericVector dt, const Rcpp::CharacterVector tzs) { if (tzs.size() != dt.size()) Rcpp::stop("`tzs` and `dt` arguments must be of the same length"); std::string tzfrom_name = tz_from_tzone_attr(dt); std::string tzto_old_name("not-a-tz"); cctz::time_zone tzto; size_t n = dt.size(); Rcpp::NumericVector out(n); for (size_t i = 0; i < n; i++) { std::string tzto_name(tzs[i]); if (tzto_name != tzto_old_name) { load_tz_or_fail(tzto_name, tzto, "CCTZ: Unrecognized timezone: \"%s\""); tzto_old_name = tzto_name; } int_fast64_t secs = floor_to_int64(dt[i]); if (secs == NA_INT64) { out[i] = NA_REAL; continue; } double rem = dt[i] - secs; sys_seconds secsfrom(secs); time_point tpfrom(secsfrom); cctz::civil_second cs = cctz::convert(tpfrom, tzto); cctz::civil_second cs_floor = cctz::civil_second(cctz::civil_day(cs)); out[i] = cs - cs_floor + rem; } return out; } lubridate/src/constants.h0000644000176200001440000000341413263152652015210 0ustar liggesusers/* * Constants for lubridate * * Author: Vitalie Spinu * Copyright (C) 2013--2018 Vitalie Spinu, Garrett Grolemund, Hadley Wickham, * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ */ #ifndef LUB_CONSTANTS_H #define LUB_CONSTANTS_H #define FALSE 0 #define TRUE 1 static const int SECONDS_IN_ONE[] = { 1, // second 60, // minute 3600, // hour 86400, // day 604800, // week 31557600 // year }; // start of each month in seconds in a common year (1 indexed) static const int sm[] = {0, 0, 2678400, 5097600, 7776000, 10368000, 13046400, 15638400, 18316800, 20995200, 23587200, 26265600, 28857600, 31536000 }; // days in months static const int mdays[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; // seconds in a day: 24*60*60 static const int daylen = 86400; // seconds between 2000-01-01 and 1970-01-01 static const int d30 = 946684800; // need 64 type to avoid overflow on integer multiplication // int64_t from stdint.h is a bit slower // potential problem: is long long 64 bit on all machines? static const long long yearlen = 31536000; // common year in sec: 365*24*60*60 #endif /* !defined LUB_CONSTANTS_H */ lubridate/src/utils.c0000644000176200001440000000750213263152652014331 0ustar liggesusers/* * C level Utilities for lubridate * * Author: Vitalie Spinu * Copyright (C) 2013--2018 Vitalie Spinu, Garrett Grolemund, Hadley Wickham, * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ */ #include "constants.h" #include "utils.h" #include #include // return adjustment (in seconds) due to leap years // y: years after (positive) or before (negative) 2000-01-01 00:00:00 int adjust_leap_years(int y, int m, int is_leap){ int SECS = 0; if ( y >= 0 ){ // ordinary leap days after 2000-01-01 00:00:00 SECS += ( y / 4 ) * daylen + daylen; if( y > 99 ) SECS += (y / 400 - y / 100) * daylen; // adjust if within a leap year if ( is_leap && m < 3 ) SECS -= daylen; } else { SECS += (y / 4) * daylen; if( y < -99 ) SECS += (y / 400 - y / 100) * daylen; if ( is_leap && m > 2 ) SECS += daylen; } return SECS; } // check if y, m, d make sense int check_ymd(int y, int m, int d, int is_leap){ int succeed = 1; if ( m == 2 ){ // no check for d > 0 because we allow missing days in parsing if ( is_leap ) succeed = d < 30; else succeed = d < 29; } else { succeed = d <= mdays[m]; } return succeed; } // parse fractional part double parse_fractional(const char **c) { double out = 0.0, factor = 0.1; while (DIGIT(**c)) { out = out + (**c - '0')*factor; factor *= 0.1; (*c)++; } return out; } /* parse N digit characters from **c. Return parsed non-negative integer. If failed to pass N chars, return -1.*/ int parse_int (const char **c, const int N, const int strict) { int tN = N, X = 0; while (DIGIT(**c) && tN > 0) { X = X * 10 + (**c - '0'); (*c)++; tN--; } if (strict && tN > 0) return -1; // not all numbers have been consumed else if (tN == N) return -1; // no parsing happened else return X; } // Find maximal partial match in `strings`. // // Increment *c and return index in 0..(length(strings)-1) if match was found, // -1 if not. Matching starts from *c, with all non-alpha-numeric characters // pre-skipped. // // - *c: pointer to a character in a C string (incremented by side effect) // - *stings: pointer to an array of C strings to be matched to // - strings_len: length of strings array int parse_alphanum(const char **c, const char **strings, const int strings_len, const char ignore_case){ // tracking array: all valid objects are marked with 1, invalid with 0 int track[strings_len]; for (int i = 0; i < strings_len; i++){ track[i] = 1; } int j = 0, out = -1, good_tracks = strings_len; while (**c && !ALPHA(**c) && !DIGIT(**c)) (*c)++; while (**c && good_tracks) { // stop when all tracks have been exhausted for (int i = 0; i < strings_len; i++){ // keep going while at least one valid track if (track[i]){ if (strings[i][j]) { if (**c == strings[i][j] || (ignore_case && (tolower(**c) == strings[i][j]))) { out = i; } else { // invalidate track i if not matching track[i] = 0; good_tracks--; } } else { // reached to the end of string i; return it if the last track good_tracks--; out = i; } } } if (good_tracks) { (*c)++; j++; } } return out; } lubridate/src/utils.h0000644000176200001440000000346413263152652014341 0ustar liggesusers/* * C level Utilities for lubridate * * Author: Vitalie Spinu * Copyright (C) 2013--2018 Vitalie Spinu, Garrett Grolemund, Hadley Wickham, * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ */ #ifndef LUB_UTILS_H #define LUB_UTILS_H typedef struct { int val; int unit; } intUnit; typedef struct { int val; double fraction; int unit; } fractionUnit; // leap year every 400 years; no leap every 100 years #define IS_LEAP(y) (((y) % 4 == 0) && !((y) % 100 == 0 && (y) % 400 != 0)) /* quick checkers */ #define ALPHA(X) (((X) >= 'a' && (X) <= 'z') || ((X) >= 'A' && (X) <= 'Z')) #define DIGIT(X) ((X) >= '0' && (X) <= '9') #define SDIGIT(X) (((X) == '-') || ((X) >= '0' && (X) <= '9')) /* skippers */ #define SKIP_NON_ALPHANUMS(X) while(*X && !(ALPHA(*X) || DIGIT(*X))) {(X)++;} #define SKIP_NON_DIGITS(X) while(*X && !(DIGIT(*X))) {(X)++;} int adjust_leap_years(int y, int m, int is_leap); int check_ymd(int y, int m, int d, int is_leap); int parse_alphanum(const char **c, const char **strings, const int strings_len, const char ignore_case); double parse_fractional (const char **c); int parse_int (const char **c, const int N, const int strict); #endif /* !defined LUB_UTILS_H */ lubridate/src/tparse.c0000644000176200001440000003327013263152652014470 0ustar liggesusers/* * Date Time Parser for lubridate * * Author: Vitalie Spinu * Copyright (C) 2013--2018 Vitalie Spinu, Garrett Grolemund, Hadley Wickham, * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ */ /* Comments: See the parse_date_time2 and fast_strptime in lubridate for how to use parse_dt from R code. See R function .parse_hms for how to use parse_hms. */ #define USE_RINTERNALS 1 // slight increase in speed #include #include #include "constants.h" #include "utils.h" static const char ltnames[][5] = {"sec", "min", "hour", "mday", "mon", "year"}; static const char *en_months[] = {"january", "february","march","april","may","june", "july","august","september","october","november","december"}; // increment **c and return month ix in 1..12 if parsing was successful, 0 if not. int parse_alpha_month(const char **c){ return (parse_alphanum(c, en_months, 12, TRUE) + 1); } SEXP C_parse_dt(SEXP str, SEXP ord, SEXP formats, SEXP lt, SEXP cutoff_2000) { // str: character vector of date-times. // ord: formats (as in strptime) or orders (as in parse_date_time) // formats: TRUE if ord is a string of formats (as in strptime) // lt: TRUE - return POSIXlt type list, FALSE - return POSIXct seconds // cutoff_2000: for `y` format years smaller or equal are read as 20th // sentry's, otherwise 19ths. R's default is 68. if ( !isString(str) ) error("Argument to parsing functions must be a character vector."); if ( !isString(ord) || (LENGTH(ord) > 1)) error("Format/orders argument must be a character vector of length 1"); R_len_t n = LENGTH(str); int is_fmt = *LOGICAL(formats); int out_lt = *LOGICAL(lt); int cut2000 = *INTEGER(cutoff_2000); // initialize to avoid -Wmaybe-uninitialized gcc warnings SEXP oYEAR = R_NilValue, oMONTH = R_NilValue, oDAY = R_NilValue, oHOUR = R_NilValue, oMIN = R_NilValue, oSEC = R_NilValue; if(out_lt){ oYEAR = PROTECT(allocVector(INTSXP, n)); oMONTH = PROTECT(allocVector(INTSXP, n)); oDAY = PROTECT(allocVector(INTSXP, n)); oHOUR = PROTECT(allocVector(INTSXP, n)); oMIN = PROTECT(allocVector(INTSXP, n)); oSEC = PROTECT(allocVector(REALSXP, n)); } else { oSEC = PROTECT(allocVector(REALSXP, n)); } const char *O = CHAR(STRING_ELT(ord, 0)); for (int i = 0; i < n; i++) { const char *c = CHAR(STRING_ELT(str, i)); const char *o = O; double secs = 0.0; // only accumulator for POSIXct case int y = 0, q = 0, m = 0, d = 0, H = 0, M = 0 , S = 0; int succeed = 1, O_format = 0, pm = 0, am = 0; // control logical // read order/format character by character while( *o && succeed ) { if( is_fmt && (*o != '%')) { // with fmt: non formatting characters should match exactly if ( *c == *o ) { c++; o++; } else succeed = 0; } else { if ( is_fmt ){ o++; // skip % } else if ( *o != 'O' && *o != 'z' && *o != 'p' && *o != 'm' && *o != 'b' && *o != 'B') { // skip non-digits // O, z, p formats are treated specially below while (*c && !DIGIT(*c)) c++; } if ( *o == 'O' ) { // Special two letter orders/formats: // Ou (Z), Oz (-0800), OO (-08:00), Oo (-08) and Ob (alpha-month) O_format = 1; o++; } else { O_format = 0; } if (!(DIGIT(*c) || O_format || *o == 'z' || *o == 'p' || *o == 'm' || *o == 'b' || *o == 'B')) { succeed = 0; } else { /* Rprintf("c=%c o=%c\n", *c, *o); */ switch( *o ) { case 'Y': // year in yyyy format y = parse_int(&c, 4, TRUE); if (y < 0) succeed = 0; break; case 'y': // year in yy format y = parse_int(&c, 2, FALSE); if (y < 0) succeed = 0; else if (y <= cut2000) y += 2000; else y += 1900; break; case 'q': // quarter q = parse_int(&c, 2, FALSE); if (!(0 < q && q < 5)) succeed = 0; break; case 'm': // month (allowing all months formats - m, b and B) SKIP_NON_ALPHANUMS(c); m = parse_int(&c, 2, FALSE); if (m == -1) { // failed m = parse_alpha_month(&c); if (m == 0) { // failed SKIP_NON_DIGITS(c); m = parse_int(&c, 2, FALSE); } } if (!(0 < m && m < 13)) succeed = 0; break; case 'b': // alpha English months (both abbreviated and long versions) case 'B': /* SKIP_NON_ALPHANUMS(c); */ m = parse_alpha_month(&c); succeed = m; /* Rprintf("succ=%d c=%c\n", succeed, *c); */ break; case 'd': // day d = parse_int(&c, 2, FALSE); if (!(0 < d && d < 32)) succeed = 0; break; case 'H': // hour 24 H = parse_int(&c, 2, FALSE); if (H > 24) succeed = 0; break; case 'I': // hour 12 H = parse_int(&c, 2, FALSE); if (H > 12) succeed = 0; break; case 'M': // minute M = parse_int(&c, 2, FALSE); if (M > 59) succeed = 0; break; case 'S': // second if( O_format && !is_fmt ){ while (*c && !DIGIT(*c)) c++; if (!*c) { succeed = 0; break; } } S = parse_int(&c, 2, FALSE); if (S < 62){ // allow leap seconds secs += S; if (O_format){ // Parse milliseconds; both . and , as decimal separator are allowed if( *c == '.' || *c == ','){ c++; secs += parse_fractional(&c); } } } else succeed = 0; break; case 'p': // AM/PM Both standard 'p' and lubridate 'Op' format SKIP_NON_ALPHANUMS(c); if (O_format) { // with Op format, p is optional (for order parsimony reasons) if (!(*c == 'P' || *c == 'p' || *c == 'A' || *c == 'a')) break; } if (*c == 'P' || *c == 'p') { pm = 1; c++; } else if (*c == 'A' || *c == 'a'){ am = 1; c++; } else { succeed = 0; } if (succeed && !(*c && (*c == 'M' || *c == 'm'))){ succeed = 0; } if (succeed) c++; break; case 'u': // %Ou: "2013-04-16T04:59:59Z" if( O_format ) if( *c == 'Z' || *c == 'z') c++; else succeed = 0; else succeed = 0; break; case 'z': // for %z: "+O100" or "+O1" or "+01:00" if( !O_format ) { if( !is_fmt ) { while (*c && *c != '+' && *c != '-' && *c != 'Z') c++; // skip non + - if( !*c ) { succeed = 0; break; }; } int Z = 0, sig; if( *c == 'Z') {c++; break;} else if ( *c == '+' ) sig = -1; else if ( *c == '-') sig = 1; else {succeed = 0; break;} c++; Z = parse_int(&c, 2, FALSE); if (Z < 0) {succeed = 0; break;} secs += sig*Z*3600; if( *c == ':' ){ c++; if ( !DIGIT(*c) ) {succeed = 0; break;} } if( DIGIT(*c) ){ Z = 0; Z = parse_int(&c, 2, FALSE); secs += sig*Z*60; } break; } // else O_format %Oz: "+0100"; pass through case 'O': // %OO: "+01:00" case 'o': // %Oo: "+01" if( O_format ){ while (*c && *c != '+' && *c != '-' ) c++; // skip non + - int Z = 0, sig; if ( *c == '+' ) sig = -1; else if ( *c == '-') sig = 1; else { succeed = 0; break; } c++; Z = parse_int(&c, 2, FALSE); if (Z < 0) {succeed = 0; break;} secs += sig*Z*3600; if( *o == 'O'){ if ( *c == ':') c++; else { succeed = 0; break; } } if ( *o != 'o' ){ // z or O Z = parse_int(&c, 2, FALSE); if (Z < 0) {succeed = 0; break;} secs += sig*Z*60; } } else error("Unrecognized format '%c' supplied", *o); break; default: error("Unrecognized format %c supplied", *o); } o++; } } } // skip all remaining non digits if( !is_fmt ) while (*c && !DIGIT(*c)) c++; // If at least one subparser hasn't finished it's a failure. if ( *c || *o ) succeed = 0; int is_leap = 0; // adjust months for quarter if (q > 1) m += (q - 1) * 3 + 1; if (succeed) { // leap year every 400 years; no leap every 100 years is_leap = IS_LEAP(y); // check month if (m == 2){ // no check for d > 0 because we allow missing days in parsing if (is_leap) succeed = d < 30; else succeed = d < 29; } else { succeed = d <= mdays[m]; } } // allow missing months and days if (m == 0) m = 1; if (d == 0) d = 1; if(pm){ if(H > 12) succeed = 0; else if (H < 12) H += 12; } if (am){ if (H > 12) succeed = 0; else if (H == 12) H = 0; } if (succeed) { if(out_lt){ INTEGER(oYEAR)[i] = y - 1900; INTEGER(oMONTH)[i] = m - 1; INTEGER(oDAY)[i] = d; INTEGER(oHOUR)[i] = H; INTEGER(oMIN)[i] = M; REAL(oSEC)[i] = secs; } else { secs += sm[m]; secs += (d - 1) * 86400; secs += H * 3600; secs += M * 60; // process leap years y -= 2000; secs += y * yearlen; secs += adjust_leap_years(y, m, is_leap); REAL(oSEC)[i] = secs + d30; } } else { if(out_lt){ INTEGER(oYEAR)[i] = NA_INTEGER; INTEGER(oMONTH)[i] = NA_INTEGER; INTEGER(oDAY)[i] = NA_INTEGER; INTEGER(oHOUR)[i] = NA_INTEGER; INTEGER(oMIN)[i] = NA_INTEGER; REAL(oSEC)[i] = NA_REAL; } else { REAL(oSEC)[i] = NA_REAL; } } } if (out_lt){ SEXP names, out; PROTECT(names = allocVector(STRSXP, 6)); for(int i = 0; i < 6; i++) SET_STRING_ELT(names, i, mkChar(ltnames[i])); PROTECT(out = allocVector(VECSXP, 6)); SET_VECTOR_ELT(out, 0, oSEC); SET_VECTOR_ELT(out, 1, oMIN); SET_VECTOR_ELT(out, 2, oHOUR); SET_VECTOR_ELT(out, 3, oDAY); SET_VECTOR_ELT(out, 4, oMONTH); SET_VECTOR_ELT(out, 5, oYEAR); setAttrib(out, R_NamesSymbol, names); UNPROTECT(8); return out; } else { UNPROTECT(1); return oSEC; } } // STR: string in HxMyS format where x and y are arbitrary non-numeric separators // ORD: orders. Can be any combination of "h", "m" and "s" // RETURN: numeric vector (H1 M1 S1 H2 M2 S2 ...) SEXP C_parse_hms(SEXP str, SEXP ord) { if (TYPEOF(str) != STRSXP) error("HMS argument must be a character vector"); if ((TYPEOF(ord) != STRSXP) || (LENGTH(ord) > 1)) error("Orders vector must be a character vector of length 1"); int n = LENGTH(str); int len = 3*n; const char *O = CHAR(STRING_ELT(ord, 0)); SEXP res; double *data; res = allocVector(REALSXP, len); data = REAL(res); for (int i = 0; i < n; i++) { const char *c = CHAR(STRING_ELT(str, i)); const char *o = O; int H=0, M=0, j=i*3; int sign = 1; double S=0.0; while (*c && !SDIGIT(*c)) c++; if (SDIGIT(*c)) { while( *o ){ if (*c == '-'){ sign = -1; c++; } switch( *o ) { case 'H': if(!DIGIT(*c)) {data[j] = NA_REAL; break;} while (DIGIT(*c)) { H = H * 10 + (*c - '0'); c++; } data[j] = H * sign; break; case 'M': if(!DIGIT(*c)) {data[j+1] = NA_REAL; break;} while (DIGIT(*c)) { M = M * 10 + (*c - '0'); c++; } data[j+1]= M * sign; break; case 'S': if(!DIGIT(*c)) {data[j+2] = NA_REAL; break;} while (DIGIT(*c) ) { S = S * 10 + (*c - '0'); c++; } // both . and , as decimal Seconds separator are allowed if( *c == '.' || *c == ','){ double ms = 0.0, msfact = 0.1; c++; while (DIGIT(*c)) { ms = ms + (*c - '0')*msfact; msfact *= 0.1; c++; } S += ms; } data[j+2] = S * sign; break; default: error("Unrecognized format %c supplied", *o); } while (*c && !SDIGIT(*c)) c++; sign = 1; o++; } } // unfinished parsing, return NA if ( *c || *o ){ data[j] = NA_REAL; data[j+1] = NA_REAL; data[j+2] = NA_REAL; } } return res; } lubridate/src/datetime.c0000644000176200001440000001076613263152652014773 0ustar liggesusers/* * Datetime Constructor for lubridate * * Author: Vitalie Spinu * Copyright (C) 2013--2018 Vitalie Spinu, Garrett Grolemund, Hadley Wickham, * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ */ #define USE_RINTERNALS 1 #include #include #include "constants.h" #include "utils.h" SEXP C_make_dt(SEXP year, SEXP month, SEXP day, SEXP hour, SEXP minute, SEXP second) { if(!isInteger(year)) error("year must be integer"); if(!isInteger(month)) error("month must be integer"); if(!isInteger(day)) error("day must be integer"); if(!isInteger(hour)) error("hour must be integer"); if(!isInteger(minute)) error("minute must be integer"); if(!isNumeric(second)) error("second must be numeric"); R_len_t n = LENGTH(year); if(n != LENGTH(month)) error("length of 'month' vector is not the same as that of 'year'"); if(n != LENGTH(day)) error("length of 'day' vector is not the same as that of 'year'"); if(n != LENGTH(hour)) error("length of 'hour' vector is not the same as that of 'year'"); if(n != LENGTH(minute)) error("length of 'minute' vector is not the same as that of 'year'"); if(n != LENGTH(second)) error("length of 'second' vector is not the same as that of 'year'"); int* pyear = INTEGER(year); int* pmonth = INTEGER(month); int* pday = INTEGER(day); int* phour = INTEGER(hour); int* pminute = INTEGER(minute); int int_second = TYPEOF(second) == INTSXP; SEXP res = allocVector(REALSXP, n); double *data = REAL(res); for(int i = 0; i < n; i++) { // main accumulator double SECS = 0.0; int y = pyear[i]; int m = pmonth[i]; int d = pday[i]; int H = phour[i]; int M = pminute[i]; int naS; double S; if(int_second){ S = (double) INTEGER(second)[i]; naS = INTEGER(second)[i] == NA_INTEGER; } else { S = REAL(second)[i]; naS = ISNA(S); } if(naS || y == NA_INTEGER || m == NA_INTEGER || d == NA_INTEGER || H == NA_INTEGER || M == NA_INTEGER) { data[i] = NA_REAL; } else { if ( 0 < m && m < 13 ) SECS += sm[m]; else { data[i] = NA_REAL; continue; } if ( 0 < d && d < 32 ) SECS += (d - 1) * 86400; else { data[i] = NA_REAL; continue; } if( H < 25 ) SECS += H * 3600; else { data[i] = NA_REAL; continue; } if ( M < 61 ) SECS += M * 60; else{ data[i] = NA_REAL; continue; } // allow leap seconds if ( S < 62 ) { SECS += S; } else { data[i] = NA_REAL; continue; } int is_leap = IS_LEAP(y); if(check_ymd(y, m, d, is_leap)){ SECS += d30; y -= 2000; SECS += y * yearlen; SECS += adjust_leap_years(y, m, is_leap); data[i] = SECS; } else { data[i] = NA_REAL; } } } return res; } SEXP C_make_d(SEXP year, SEXP month, SEXP day) { if(!isInteger(year)) error("year must be integer"); if(!isInteger(month)) error("month must be integer"); if(!isInteger(day)) error("day must be integer"); R_len_t n = LENGTH(year); if(n != LENGTH(month)) error("length of 'month' vector is not the same as that of 'year'"); if(n != LENGTH(day)) error("length of 'day' vector is not the same as that of 'year'"); int* pyear = INTEGER(year); int* pmonth = INTEGER(month); int* pday = INTEGER(day); SEXP res = allocVector(REALSXP, n); double *data = REAL(res); for(int i = 0; i < n; i++) { // main accumulator double SECS = 0.0; int y = pyear[i]; int m = pmonth[i]; int d = pday[i]; if(y == NA_INTEGER || m == NA_INTEGER || d == NA_INTEGER) { data[i] = NA_REAL; } else { if ( 0 < m && m < 13 ) SECS += sm[m]; else { data[i] = NA_REAL; continue; } if ( 0 < d && d < 32 ) SECS += (d - 1) * 86400; else { data[i] = NA_REAL; continue; } int is_leap = IS_LEAP(y); if(check_ymd(y, m, d, is_leap)){ SECS += d30; y -= 2000; SECS += y * yearlen; SECS += adjust_leap_years(y, m, is_leap); data[i] = SECS; } else { data[i] = NA_REAL; } } } return res; } lubridate/src/RcppExports.cpp0000644000176200001440000001311213263152652016014 0ustar liggesusers// Generated by using Rcpp::compileAttributes() -> do not edit by hand // Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 #include using namespace Rcpp; // C_local_tz Rcpp::CharacterVector C_local_tz(); RcppExport SEXP _lubridate_C_local_tz() { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; rcpp_result_gen = Rcpp::wrap(C_local_tz()); return rcpp_result_gen; END_RCPP } // C_valid_tz Rcpp::LogicalVector C_valid_tz(const Rcpp::CharacterVector& tz_name); RcppExport SEXP _lubridate_C_valid_tz(SEXP tz_nameSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::CharacterVector& >::type tz_name(tz_nameSEXP); rcpp_result_gen = Rcpp::wrap(C_valid_tz(tz_name)); return rcpp_result_gen; END_RCPP } // C_update_dt Rcpp::newDatetimeVector C_update_dt(const Rcpp::NumericVector& dt, const Rcpp::IntegerVector& year, const Rcpp::IntegerVector& month, const Rcpp::IntegerVector& yday, const Rcpp::IntegerVector& mday, const Rcpp::IntegerVector& wday, const Rcpp::IntegerVector& hour, const Rcpp::IntegerVector& minute, const Rcpp::NumericVector& second, const SEXP tz, const bool roll, const int week_start); RcppExport SEXP _lubridate_C_update_dt(SEXP dtSEXP, SEXP yearSEXP, SEXP monthSEXP, SEXP ydaySEXP, SEXP mdaySEXP, SEXP wdaySEXP, SEXP hourSEXP, SEXP minuteSEXP, SEXP secondSEXP, SEXP tzSEXP, SEXP rollSEXP, SEXP week_startSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type dt(dtSEXP); Rcpp::traits::input_parameter< const Rcpp::IntegerVector& >::type year(yearSEXP); Rcpp::traits::input_parameter< const Rcpp::IntegerVector& >::type month(monthSEXP); Rcpp::traits::input_parameter< const Rcpp::IntegerVector& >::type yday(ydaySEXP); Rcpp::traits::input_parameter< const Rcpp::IntegerVector& >::type mday(mdaySEXP); Rcpp::traits::input_parameter< const Rcpp::IntegerVector& >::type wday(wdaySEXP); Rcpp::traits::input_parameter< const Rcpp::IntegerVector& >::type hour(hourSEXP); Rcpp::traits::input_parameter< const Rcpp::IntegerVector& >::type minute(minuteSEXP); Rcpp::traits::input_parameter< const Rcpp::NumericVector& >::type second(secondSEXP); Rcpp::traits::input_parameter< const SEXP >::type tz(tzSEXP); Rcpp::traits::input_parameter< const bool >::type roll(rollSEXP); Rcpp::traits::input_parameter< const int >::type week_start(week_startSEXP); rcpp_result_gen = Rcpp::wrap(C_update_dt(dt, year, month, yday, mday, wday, hour, minute, second, tz, roll, week_start)); return rcpp_result_gen; END_RCPP } // C_force_tz Rcpp::newDatetimeVector C_force_tz(const Rcpp::NumericVector dt, const Rcpp::CharacterVector tz, const bool roll); RcppExport SEXP _lubridate_C_force_tz(SEXP dtSEXP, SEXP tzSEXP, SEXP rollSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type dt(dtSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz(tzSEXP); Rcpp::traits::input_parameter< const bool >::type roll(rollSEXP); rcpp_result_gen = Rcpp::wrap(C_force_tz(dt, tz, roll)); return rcpp_result_gen; END_RCPP } // C_force_tzs Rcpp::newDatetimeVector C_force_tzs(const Rcpp::NumericVector dt, const Rcpp::CharacterVector tzs, const Rcpp::CharacterVector tz_out, const bool roll); RcppExport SEXP _lubridate_C_force_tzs(SEXP dtSEXP, SEXP tzsSEXP, SEXP tz_outSEXP, SEXP rollSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type dt(dtSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tzs(tzsSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tz_out(tz_outSEXP); Rcpp::traits::input_parameter< const bool >::type roll(rollSEXP); rcpp_result_gen = Rcpp::wrap(C_force_tzs(dt, tzs, tz_out, roll)); return rcpp_result_gen; END_RCPP } // C_local_time Rcpp::NumericVector C_local_time(const Rcpp::NumericVector dt, const Rcpp::CharacterVector tzs); RcppExport SEXP _lubridate_C_local_time(SEXP dtSEXP, SEXP tzsSEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; Rcpp::traits::input_parameter< const Rcpp::NumericVector >::type dt(dtSEXP); Rcpp::traits::input_parameter< const Rcpp::CharacterVector >::type tzs(tzsSEXP); rcpp_result_gen = Rcpp::wrap(C_local_time(dt, tzs)); return rcpp_result_gen; END_RCPP } RcppExport SEXP C_make_d(SEXP, SEXP, SEXP); RcppExport SEXP C_parse_dt(SEXP, SEXP, SEXP, SEXP, SEXP); RcppExport SEXP C_parse_hms(SEXP, SEXP); RcppExport SEXP C_parse_period(SEXP); static const R_CallMethodDef CallEntries[] = { {"_lubridate_C_local_tz", (DL_FUNC) &_lubridate_C_local_tz, 0}, {"_lubridate_C_valid_tz", (DL_FUNC) &_lubridate_C_valid_tz, 1}, {"_lubridate_C_update_dt", (DL_FUNC) &_lubridate_C_update_dt, 12}, {"_lubridate_C_force_tz", (DL_FUNC) &_lubridate_C_force_tz, 3}, {"_lubridate_C_force_tzs", (DL_FUNC) &_lubridate_C_force_tzs, 4}, {"_lubridate_C_local_time", (DL_FUNC) &_lubridate_C_local_time, 2}, {"C_make_d", (DL_FUNC) &C_make_d, 3}, {"C_parse_dt", (DL_FUNC) &C_parse_dt, 5}, {"C_parse_hms", (DL_FUNC) &C_parse_hms, 2}, {"C_parse_period", (DL_FUNC) &C_parse_period, 1}, {NULL, NULL, 0} }; RcppExport void R_init_lubridate(DllInfo *dll) { R_registerRoutines(dll, NULL, CallEntries, NULL, NULL); R_useDynamicSymbols(dll, FALSE); } lubridate/src/period.c0000644000176200001440000001121713263152652014451 0ustar liggesusers/* * Period and Duration Parser for lubridate * * Author: Vitalie Spinu * Copyright (C) 2013--2018 Vitalie Spinu, Garrett Grolemund, Hadley Wickham, * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, a copy is available at * http://www.r-project.org/Licenses/ */ #define USE_RINTERNALS 1 // slight increase in speed #include #include #include "constants.h" #include "utils.h" static const char *EN_UNITS[] = {"S", "secs", "seconds", "M", "mins", "minutes", "H", "hours", // 6 "D", "days", // 8 "W", "weeks", // 10 "M", "months", // 12 "Y", "years", // 14 // ISO period delimiters "M", // 16 "P", // 17 "T" // 18 }; #define N_EN_UNITS 19 // S=0, M=1, H=2, d=3, w=4, m=5, y=6 static const char *PERIOD_UNITS[] = {"seconds", "minutes", "hours", "days", "weeks", "months", "years"}; #define N_PERIOD_UNITS 7 fractionUnit parse_period_unit (const char **c) { // units: invalid=-1, S=0, M=1, H=2, d=3, w=4, m=5, y=6 // SKIP_NON_ALPHANUMS(*c); // why this macro doesn't work here? while(**c && !(ALPHA(**c) || DIGIT(**c) || **c == '.')) (*c)++;; fractionUnit out; out.unit = -1; out.val = parse_int(c, 100, FALSE); if (**c == '.') { (*c)++; // allow fractions without leading 0 if (out.val == -1) out.val = 0; out.fraction = parse_fractional(c); } else { out.fraction = 0.0; } if(**c){ out.unit = parse_alphanum(c, EN_UNITS, N_EN_UNITS, 0); if (out.unit < 0 || out.unit > 16) { return out; } else { // if only unit name supplied, default to 1 units if(out.val == -1) out.val = 1; if (out.unit < 3) out.unit = 0; // seconds else if (out.unit < 6) out.unit = 1; // minutes else if (out.unit < 16) out.unit = (out.unit - 6)/2 + 2; return out; } } else { return out; } } void parse_period_1 (const char **c, double ret[N_PERIOD_UNITS]){ int P = 0; // ISO period flag int parsed1 = 0; while (**c) { fractionUnit fu = parse_period_unit(c); /* Rprintf("P:%d UNIT:%d\n", P, fu.unit); */ if (fu.unit >= 0) { if (fu.unit == 17) { // ISO P P = 1; } else if (fu.unit == 18) { // ISO T P = 0; } else { if (fu.unit == 16) { // month or minute fu.unit = P ? 5 : 1; } parsed1 = 1; ret[fu.unit] += fu.val; if (fu.fraction > 0) { if (fu.unit == 0) ret[fu.unit] += fu.fraction; else ret[0] += fu.fraction * SECONDS_IN_ONE[fu.unit]; } } } else { ret[0] = NA_REAL; break; } } if (!parsed1) { ret[0] = NA_REAL; } } SEXP period_names() { SEXP names = PROTECT(allocVector(STRSXP, N_PERIOD_UNITS)); for (int i = 0; i < N_PERIOD_UNITS; i++) { SET_STRING_ELT(names, i, mkChar(PERIOD_UNITS[i])); } UNPROTECT(1); return names; } SEXP C_parse_period(SEXP str) { if (TYPEOF(str) != STRSXP) error("STR argument must be a character vector"); int n = LENGTH(str); // store parsed units in a N_PERIOD_UNITS x n matrix SEXP out = PROTECT(allocMatrix(REALSXP, N_PERIOD_UNITS, n)); double *data = REAL(out); for (int i = 0; i < n; i++) { const char *c = CHAR(STRING_ELT(str, i)); double ret[N_PERIOD_UNITS] = {0}; parse_period_1(&c, ret); int j = i * N_PERIOD_UNITS; for(int k = 0; k < N_PERIOD_UNITS; k++) { data[j + k] = ret[k]; } } // Not adding names as mat[i, ] retains names when mat is a single column, thus // requiring additional pre-processing at R level /* SEXP dimnames = PROTECT(allocVector(VECSXP, 2)); */ /* SET_VECTOR_ELT(dimnames, 0, period_names()); */ /* SET_VECTOR_ELT(dimnames, 1, R_NilValue); */ /* setAttrib(out, R_DimNamesSymbol, dimnames); */ UNPROTECT(1); return out; } lubridate/src/cctz/0000755000176200001440000000000013201152061013746 5ustar liggesuserslubridate/src/cctz/src/0000755000176200001440000000000013263152652014553 5ustar liggesuserslubridate/src/cctz/src/time_zone_if.h0000644000176200001440000000431613263152652017377 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CCTZ_TIME_ZONE_IF_H_ #define CCTZ_TIME_ZONE_IF_H_ #include #include #include #include #include "civil_time.h" #include "time_zone.h" namespace cctz { // A simple interface used to hide time-zone complexities from time_zone::Impl. // Subclasses implement the functions for civil-time conversions in the zone. class TimeZoneIf { public: // A factory function for TimeZoneIf implementations. static std::unique_ptr Load(const std::string& name); virtual ~TimeZoneIf() {} virtual time_zone::absolute_lookup BreakTime( const time_point& tp) const = 0; virtual time_zone::civil_lookup MakeTime( const civil_second& cs) const = 0; virtual std::string Description() const = 0; virtual bool NextTransition(time_point* tp) const = 0; virtual bool PrevTransition(time_point* tp) const = 0; protected: TimeZoneIf() {} }; // Convert between time_point and a count of seconds since // the Unix epoch. We assume that the std::chrono::system_clock and the // Unix clock are second aligned, but not that they share an epoch. inline std::int_fast64_t ToUnixSeconds(const time_point& tp) { return (tp - std::chrono::time_point_cast( std::chrono::system_clock::from_time_t(0))) .count(); } inline time_point FromUnixSeconds(std::int_fast64_t t) { return std::chrono::time_point_cast( std::chrono::system_clock::from_time_t(0)) + sys_seconds(t); } } // namespace cctz #endif // CCTZ_TIME_ZONE_IF_H_ lubridate/src/cctz/src/time_zone_posix.cc0000644000176200001440000001077513263152652020307 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "time_zone_posix.h" #include #include #include #include namespace cctz { namespace { const char kDigits[] = "0123456789"; const char* ParseInt(const char* p, int min, int max, int* vp) { int value = 0; const char* op = p; const int kMaxInt = std::numeric_limits::max(); for (; const char* dp = strchr(kDigits, *p); ++p) { int d = static_cast(dp - kDigits); if (d >= 10) break; // '\0' if (value > kMaxInt / 10) return nullptr; value *= 10; if (value > kMaxInt - d) return nullptr; value += d; } if (p == op || value < min || value > max) return nullptr; *vp = value; return p; } // abbr = <.*?> | [^-+,\d]{3,} const char* ParseAbbr(const char* p, std::string* abbr) { const char* op = p; if (*p == '<') { // special zoneinfo <...> form while (*++p != '>') { if (*p == '\0') return nullptr; } abbr->assign(op + 1, static_cast(p - op) - 1); return ++p; } while (*p != '\0') { if (strchr("-+,", *p)) break; if (strchr(kDigits, *p)) break; ++p; } if (p - op < 3) return nullptr; abbr->assign(op, static_cast(p - op)); return p; } // offset = [+|-]hh[:mm[:ss]] (aggregated into single seconds value) const char* ParseOffset(const char* p, int min_hour, int max_hour, int sign, std::int_fast32_t* offset) { if (p == nullptr) return nullptr; if (*p == '+' || *p == '-') { if (*p++ == '-') sign = -sign; } int hours = 0; int minutes = 0; int seconds = 0; p = ParseInt(p, min_hour, max_hour, &hours); if (p == nullptr) return nullptr; if (*p == ':') { p = ParseInt(p + 1, 0, 59, &minutes); if (p == nullptr) return nullptr; if (*p == ':') { p = ParseInt(p + 1, 0, 59, &seconds); if (p == nullptr) return nullptr; } } *offset = sign * ((((hours * 60) + minutes) * 60) + seconds); return p; } // datetime = ( Jn | n | Mm.w.d ) [ / offset ] const char* ParseDateTime(const char* p, PosixTransition* res) { if (p != nullptr && *p == ',') { if (*++p == 'M') { int month = 0; if ((p = ParseInt(p + 1, 1, 12, &month)) != nullptr && *p == '.') { int week = 0; if ((p = ParseInt(p + 1, 1, 5, &week)) != nullptr && *p == '.') { int weekday = 0; if ((p = ParseInt(p + 1, 0, 6, &weekday)) != nullptr) { res->date.fmt = PosixTransition::M; res->date.m.month = static_cast(month); res->date.m.week = static_cast(week); res->date.m.weekday = static_cast(weekday); } } } } else if (*p == 'J') { int day = 0; if ((p = ParseInt(p + 1, 1, 365, &day)) != nullptr) { res->date.fmt = PosixTransition::J; res->date.j.day = static_cast(day); } } else { int day = 0; if ((p = ParseInt(p, 0, 365, &day)) != nullptr) { res->date.fmt = PosixTransition::N; res->date.j.day = static_cast(day); } } } if (p != nullptr) { res->time.offset = 2 * 60 * 60; // default offset is 02:00:00 if (*p == '/') p = ParseOffset(p + 1, -167, 167, 1, &res->time.offset); } return p; } } // namespace // spec = std offset [ dst [ offset ] , datetime , datetime ] bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res) { const char* p = spec.c_str(); if (*p == ':') return false; p = ParseAbbr(p, &res->std_abbr); p = ParseOffset(p, 0, 24, -1, &res->std_offset); if (p == nullptr) return false; if (*p == '\0') return true; p = ParseAbbr(p, &res->dst_abbr); if (p == nullptr) return false; res->dst_offset = res->std_offset + (60 * 60); // default if (*p != ',') p = ParseOffset(p, 0, 24, -1, &res->dst_offset); p = ParseDateTime(p, &res->dst_start); p = ParseDateTime(p, &res->dst_end); return p != nullptr && *p == '\0'; } } // namespace cctz lubridate/src/cctz/src/tzfile.h0000644000176200001440000000732413263152652016227 0ustar liggesusers#ifndef TZFILE_H #define TZFILE_H /* ** This file is in the public domain, so clarified as of ** 1996-06-05 by Arthur David Olson. */ /* ** This header is for use ONLY with the time conversion code. ** There is no guarantee that it will remain unchanged, ** or that it will remain at all. ** Do NOT copy it to any system include directory. ** Thank you! */ /* ** Information about time zone files. */ #ifndef TZDIR #define TZDIR "/usr/local/etc/zoneinfo" /* Time zone object file directory */ #endif /* !defined TZDIR */ #ifndef TZDEFAULT #define TZDEFAULT "localtime" #endif /* !defined TZDEFAULT */ #ifndef TZDEFRULES #define TZDEFRULES "posixrules" #endif /* !defined TZDEFRULES */ /* ** Each file begins with. . . */ #define TZ_MAGIC "TZif" struct tzhead { char tzh_magic[4]; /* TZ_MAGIC */ char tzh_version[1]; /* '\0' or '2' or '3' as of 2013 */ char tzh_reserved[15]; /* reserved; must be zero */ char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ char tzh_leapcnt[4]; /* coded number of leap seconds */ char tzh_timecnt[4]; /* coded number of transition times */ char tzh_typecnt[4]; /* coded number of local time types */ char tzh_charcnt[4]; /* coded number of abbr. chars */ }; /* ** . . .followed by. . . ** ** tzh_timecnt (char [4])s coded transition times a la time(2) ** tzh_timecnt (unsigned char)s types of local time starting at above ** tzh_typecnt repetitions of ** one (char [4]) coded UT offset in seconds ** one (unsigned char) used to set tm_isdst ** one (unsigned char) that's an abbreviation list index ** tzh_charcnt (char)s '\0'-terminated zone abbreviations ** tzh_leapcnt repetitions of ** one (char [4]) coded leap second transition times ** one (char [4]) total correction after above ** tzh_ttisstdcnt (char)s indexed by type; if 1, transition ** time is standard time, if 0, ** transition time is wall clock time ** if absent, transition times are ** assumed to be wall clock time ** tzh_ttisgmtcnt (char)s indexed by type; if 1, transition ** time is UT, if 0, ** transition time is local time ** if absent, transition times are ** assumed to be local time */ /* ** If tzh_version is '2' or greater, the above is followed by a second instance ** of tzhead and a second instance of the data in which each coded transition ** time uses 8 rather than 4 chars, ** then a POSIX-TZ-environment-variable-style string for use in handling ** instants after the last transition time stored in the file ** (with nothing between the newlines if there is no POSIX representation for ** such instants). ** ** If tz_version is '3' or greater, the above is extended as follows. ** First, the POSIX TZ string's hour offset may range from -167 ** through 167 as compared to the POSIX-required 0 through 24. ** Second, its DST start time may be January 1 at 00:00 and its stop ** time December 31 at 24:00 plus the difference between DST and ** standard time, indicating DST all year. */ /* ** In the current implementation, "tzset()" refuses to deal with files that ** exceed any of the limits below. */ #ifndef TZ_MAX_TIMES #define TZ_MAX_TIMES 2000 #endif /* !defined TZ_MAX_TIMES */ #ifndef TZ_MAX_TYPES /* This must be at least 17 for Europe/Samara and Europe/Vilnius. */ #define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ #endif /* !defined TZ_MAX_TYPES */ #ifndef TZ_MAX_CHARS #define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ /* (limited by what unsigned chars can hold) */ #endif /* !defined TZ_MAX_CHARS */ #ifndef TZ_MAX_LEAPS #define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ #endif /* !defined TZ_MAX_LEAPS */ #endif /* !defined TZFILE_H */ lubridate/src/cctz/src/time_zone_fixed.h0000644000176200001440000000346413263152652020103 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CCTZ_TIME_ZONE_FIXED_H_ #define CCTZ_TIME_ZONE_FIXED_H_ #include #include "time_zone.h" namespace cctz { // Helper functions for dealing with the names and abbreviations // of time zones that are a fixed offset (seconds east) from UTC. // FixedOffsetFromName() extracts the offset from a valid fixed-offset // name, while FixedOffsetToName() and FixedOffsetToAbbr() generate // the canonical zone name and abbreviation respectively for the given // offset. // // A fixed-offset name looks like "Fixed/UTC<+->::". // Its abbreviation is of the form "UTC(<+->H?H(MM(SS)?)?)?" where the // optional pieces are omitted when their values are zero. (Note that // the sign is the opposite of that used in a POSIX TZ specification.) // // Note: FixedOffsetFromName() fails on syntax errors or when the parsed // offset exceeds 24 hours. FixedOffsetToName() and FixedOffsetToAbbr() // both produce "UTC" when the argument offset exceeds 24 hours. bool FixedOffsetFromName(const std::string& name, sys_seconds* offset); std::string FixedOffsetToName(const sys_seconds& offset); std::string FixedOffsetToAbbr(const sys_seconds& offset); } // namespace cctz #endif // CCTZ_TIME_ZONE_FIXED_H_ lubridate/src/cctz/src/time_zone_info.cc0000644000176200001440000010570313263152652020074 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // This file implements the TimeZoneIf interface using the "zoneinfo" // data provided by the IANA Time Zone Database (i.e., the only real game // in town). // // TimeZoneInfo represents the history of UTC-offset changes within a time // zone. Most changes are due to daylight-saving rules, but occasionally // shifts are made to the time-zone's base offset. The database only attempts // to be definitive for times since 1970, so be wary of local-time conversions // before that. Also, rule and zone-boundary changes are made at the whim // of governments, so the conversion of future times needs to be taken with // a grain of salt. // // For more information see tzfile(5), http://www.iana.org/time-zones, or // http://en.wikipedia.org/wiki/Zoneinfo. // // Note that we assume the proleptic Gregorian calendar and 60-second // minutes throughout. #include "time_zone_info.h" #include #include #include #include #include #include #include #include #include #include #include #include #include "civil_time.h" #include "time_zone_fixed.h" #include "time_zone_posix.h" namespace cctz_extension { namespace { // A default for cctz_extension::zone_info_source_factory, which simply // defers to the fallback factory. std::unique_ptr DefaultFactory( const std::string& name, const std::function( const std::string& name)>& fallback_factory) { return fallback_factory(name); } } // namespace // A "weak" definition for cctz_extension::zone_info_source_factory. // The user may override this with their own "strong" definition (see // zone_info_source.h). #if defined(_MSC_VER) extern ZoneInfoSourceFactory zone_info_source_factory; extern ZoneInfoSourceFactory default_factory = DefaultFactory; #if defined(_M_IX86) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZA=?default_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@ABV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZA") #elif defined(_M_IA_64) || defined(_M_AMD64) #pragma comment( \ linker, \ "/alternatename:?zone_info_source_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZEA=?default_factory@cctz_extension@@3P6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@3@AEBV?$function@$$A6A?AV?$unique_ptr@VZoneInfoSource@cctz@@U?$default_delete@VZoneInfoSource@cctz@@@std@@@std@@AEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@@Z@3@@ZEA") #else #error Unsupported MSVC platform #endif // _MSC_VER #else ZoneInfoSourceFactory zone_info_source_factory __attribute__((weak)) = DefaultFactory; #endif } // namespace cctz_extension namespace cctz { namespace { inline bool IsLeap(cctz::year_t year) { return (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0); } // The number of days in non-leap and leap years respectively. const std::int_least32_t kDaysPerYear[2] = {365, 366}; // The day offsets of the beginning of each (1-based) month in non-leap and // leap years respectively (e.g., 335 days before December in a leap year). const std::int_least16_t kMonthOffsets[2][1 + 12 + 1] = { {-1, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365}, {-1, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}, }; // We reject leap-second encoded zoneinfo and so assume 60-second minutes. const std::int_least32_t kSecsPerDay = 24 * 60 * 60; // 400-year chunks always have 146097 days (20871 weeks). const std::int_least64_t kSecsPer400Years = 146097LL * kSecsPerDay; // Like kDaysPerYear[] but scaled up by a factor of kSecsPerDay. const std::int_least32_t kSecsPerYear[2] = { 365 * kSecsPerDay, 366 * kSecsPerDay, }; // Single-byte, unsigned numeric values are encoded directly. inline std::uint_fast8_t Decode8(const char* cp) { return static_cast(*cp) & 0xff; } // Multi-byte, numeric values are encoded using a MSB first, // twos-complement representation. These helpers decode, from // the given address, 4-byte and 8-byte values respectively. // Note: If int_fastXX_t == intXX_t and this machine is not // twos complement, then there will be at least one input value // we cannot represent. std::int_fast32_t Decode32(const char* cp) { std::uint_fast32_t v = 0; for (int i = 0; i != (32 / 8); ++i) v = (v << 8) | Decode8(cp++); const std::int_fast32_t s32max = 0x7fffffff; const auto s32maxU = static_cast(s32max); if (v <= s32maxU) return static_cast(v); return static_cast(v - s32maxU - 1) - s32max - 1; } std::int_fast64_t Decode64(const char* cp) { std::uint_fast64_t v = 0; for (int i = 0; i != (64 / 8); ++i) v = (v << 8) | Decode8(cp++); const std::int_fast64_t s64max = 0x7fffffffffffffff; const auto s64maxU = static_cast(s64max); if (v <= s64maxU) return static_cast(v); return static_cast(v - s64maxU - 1) - s64max - 1; } // Generate a year-relative offset for a PosixTransition. std::int_fast64_t TransOffset(bool leap_year, int jan1_weekday, const PosixTransition& pt) { std::int_fast64_t days = 0; switch (pt.date.fmt) { case PosixTransition::J: { days = pt.date.j.day; if (!leap_year || days < kMonthOffsets[1][3]) days -= 1; break; } case PosixTransition::N: { days = pt.date.n.day; break; } case PosixTransition::M: { const bool last_week = (pt.date.m.week == 5); days = kMonthOffsets[leap_year][pt.date.m.month + last_week]; const std::int_fast64_t weekday = (jan1_weekday + days) % 7; if (last_week) { days -= (weekday + 7 - 1 - pt.date.m.weekday) % 7 + 1; } else { days += (pt.date.m.weekday + 7 - weekday) % 7; days += (pt.date.m.week - 1) * 7; } break; } } return (days * kSecsPerDay) + pt.time.offset; } inline time_zone::civil_lookup MakeUnique(const time_point& tp) { time_zone::civil_lookup cl; cl.kind = time_zone::civil_lookup::UNIQUE; cl.pre = cl.trans = cl.post = tp; return cl; } inline time_zone::civil_lookup MakeUnique(std::int_fast64_t unix_time) { return MakeUnique(FromUnixSeconds(unix_time)); } inline time_zone::civil_lookup MakeSkipped(const Transition& tr, const civil_second& cs) { time_zone::civil_lookup cl; cl.kind = time_zone::civil_lookup::SKIPPED; cl.pre = FromUnixSeconds(tr.unix_time - 1 + (cs - tr.prev_civil_sec)); cl.trans = FromUnixSeconds(tr.unix_time); cl.post = FromUnixSeconds(tr.unix_time - (tr.civil_sec - cs)); return cl; } inline time_zone::civil_lookup MakeRepeated(const Transition& tr, const civil_second& cs) { time_zone::civil_lookup cl; cl.kind = time_zone::civil_lookup::REPEATED; cl.pre = FromUnixSeconds(tr.unix_time - 1 - (tr.prev_civil_sec - cs)); cl.trans = FromUnixSeconds(tr.unix_time); cl.post = FromUnixSeconds(tr.unix_time + (cs - tr.civil_sec)); return cl; } inline civil_second YearShift(const civil_second& cs, cctz::year_t shift) { return civil_second(cs.year() + shift, cs.month(), cs.day(), cs.hour(), cs.minute(), cs.second()); } } // namespace // What (no leap-seconds) UTC+seconds zoneinfo would look like. bool TimeZoneInfo::ResetToBuiltinUTC(const sys_seconds& offset) { transition_types_.resize(1); TransitionType& tt(transition_types_.back()); tt.utc_offset = static_cast(offset.count()); tt.is_dst = false; tt.abbr_index = 0; transitions_.clear(); transitions_.reserve(2); for (const std::int_fast64_t unix_time : {-(1LL << 59), 2147483647LL}) { Transition& tr(*transitions_.emplace(transitions_.end())); tr.unix_time = unix_time; tr.type_index = 0; tr.civil_sec = LocalTime(tr.unix_time, tt).cs; tr.prev_civil_sec = tr.civil_sec - 1; } default_transition_type_ = 0; abbreviations_ = FixedOffsetToAbbr(offset); abbreviations_.append(1, '\0'); // add NUL future_spec_.clear(); // never needed for a fixed-offset zone extended_ = false; tt.civil_max = LocalTime(sys_seconds::max().count(), tt).cs; tt.civil_min = LocalTime(sys_seconds::min().count(), tt).cs; transitions_.shrink_to_fit(); return true; } // Builds the in-memory header using the raw bytes from the file. bool TimeZoneInfo::Header::Build(const tzhead& tzh) { std::int_fast32_t v; if ((v = Decode32(tzh.tzh_timecnt)) < 0) return false; timecnt = static_cast(v); if ((v = Decode32(tzh.tzh_typecnt)) < 0) return false; typecnt = static_cast(v); if ((v = Decode32(tzh.tzh_charcnt)) < 0) return false; charcnt = static_cast(v); if ((v = Decode32(tzh.tzh_leapcnt)) < 0) return false; leapcnt = static_cast(v); if ((v = Decode32(tzh.tzh_ttisstdcnt)) < 0) return false; ttisstdcnt = static_cast(v); if ((v = Decode32(tzh.tzh_ttisgmtcnt)) < 0) return false; ttisgmtcnt = static_cast(v); return true; } // How many bytes of data are associated with this header. The result // depends upon whether this is a section with 4-byte or 8-byte times. std::size_t TimeZoneInfo::Header::DataLength(std::size_t time_len) const { std::size_t len = 0; len += (time_len + 1) * timecnt; // unix_time + type_index len += (4 + 1 + 1) * typecnt; // utc_offset + is_dst + abbr_index len += 1 * charcnt; // abbreviations len += (time_len + 4) * leapcnt; // leap-time + TAI-UTC len += 1 * ttisstdcnt; // UTC/local indicators len += 1 * ttisgmtcnt; // standard/wall indicators return len; } // Check that the TransitionType has the expected offset/is_dst/abbreviation. void TimeZoneInfo::CheckTransition(const std::string& name, const TransitionType& tt, std::int_fast32_t offset, bool is_dst, const std::string& abbr) const { if (tt.utc_offset != offset || tt.is_dst != is_dst || &abbreviations_[tt.abbr_index] != abbr) { std::clog << name << ": Transition" << " offset=" << tt.utc_offset << "/" << (tt.is_dst ? "DST" : "STD") << "/abbr=" << &abbreviations_[tt.abbr_index] << " does not match POSIX spec '" << future_spec_ << "'\n"; } } // zic(8) can generate no-op transitions when a zone changes rules at an // instant when there is actually no discontinuity. So we check whether // two transitions have equivalent types (same offset/is_dst/abbr). bool TimeZoneInfo::EquivTransitions(std::uint_fast8_t tt1_index, std::uint_fast8_t tt2_index) const { if (tt1_index == tt2_index) return true; const TransitionType& tt1(transition_types_[tt1_index]); const TransitionType& tt2(transition_types_[tt2_index]); if (tt1.is_dst != tt2.is_dst) return false; if (tt1.utc_offset != tt2.utc_offset) return false; if (tt1.abbr_index != tt2.abbr_index) return false; return true; } // Use the POSIX-TZ-environment-variable-style string to handle times // in years after the last transition stored in the zoneinfo data. void TimeZoneInfo::ExtendTransitions(const std::string& name, const Header& hdr) { extended_ = false; bool extending = !future_spec_.empty(); PosixTimeZone posix; if (extending && !ParsePosixSpec(future_spec_, &posix)) { std::clog << name << ": Failed to parse '" << future_spec_ << "'\n"; extending = false; } if (extending && posix.dst_abbr.empty()) { // std only // The future specification should match the last/default transition, // and that means that handling the future will fall out naturally. std::uint_fast8_t index = default_transition_type_; if (hdr.timecnt != 0) index = transitions_[hdr.timecnt - 1].type_index; const TransitionType& tt(transition_types_[index]); CheckTransition(name, tt, posix.std_offset, false, posix.std_abbr); extending = false; } if (extending && hdr.timecnt < 2) { std::clog << name << ": Too few transitions for POSIX spec\n"; extending = false; } if (!extending) { // Ensure that there is always a transition in the second half of the // time line (the BIG_BANG transition is in the first half) so that the // signed difference between a civil_second and the civil_second of its // previous transition is always representable, without overflow. const Transition& last(transitions_.back()); if (last.unix_time < 0) { const std::uint_fast8_t type_index = last.type_index; Transition& tr(*transitions_.emplace(transitions_.end())); tr.unix_time = 2147483647; // 2038-01-19T03:14:07+00:00 tr.type_index = type_index; } return; // last transition wins } // Extend the transitions for an additional 400 years using the // future specification. Years beyond those can be handled by // mapping back to a cycle-equivalent year within that range. // zic(8) should probably do this so that we don't have to. // TODO: Reduce the extension by the number of compatible // transitions already in place. transitions_.reserve(hdr.timecnt + 400 * 2 + 1); transitions_.resize(hdr.timecnt + 400 * 2); extended_ = true; // The future specification should match the last two transitions, // and those transitions should have different is_dst flags. const Transition* tr0 = &transitions_[hdr.timecnt - 1]; const Transition* tr1 = &transitions_[hdr.timecnt - 2]; const TransitionType* tt0 = &transition_types_[tr0->type_index]; const TransitionType* tt1 = &transition_types_[tr1->type_index]; const TransitionType& spring(tt0->is_dst ? *tt0 : *tt1); const TransitionType& autumn(tt0->is_dst ? *tt1 : *tt0); CheckTransition(name, spring, posix.dst_offset, true, posix.dst_abbr); CheckTransition(name, autumn, posix.std_offset, false, posix.std_abbr); // Add the transitions to tr1 and back to tr0 for each extra year. last_year_ = LocalTime(tr0->unix_time, *tt0).cs.year(); bool leap_year = IsLeap(last_year_); const civil_day jan1(last_year_, 1, 1); std::int_fast64_t jan1_time = civil_second(jan1) - civil_second(); int jan1_weekday = (static_cast(get_weekday(jan1)) + 1) % 7; Transition* tr = &transitions_[hdr.timecnt]; // next trans to fill if (LocalTime(tr1->unix_time, *tt1).cs.year() != last_year_) { // Add a single extra transition to align to a calendar year. transitions_.resize(transitions_.size() + 1); assert(tr == &transitions_[hdr.timecnt]); // no reallocation const PosixTransition& pt1(tt0->is_dst ? posix.dst_end : posix.dst_start); std::int_fast64_t tr1_offset = TransOffset(leap_year, jan1_weekday, pt1); tr->unix_time = jan1_time + tr1_offset - tt0->utc_offset; tr++->type_index = tr1->type_index; tr0 = &transitions_[hdr.timecnt]; tr1 = &transitions_[hdr.timecnt - 1]; tt0 = &transition_types_[tr0->type_index]; tt1 = &transition_types_[tr1->type_index]; } const PosixTransition& pt1(tt0->is_dst ? posix.dst_end : posix.dst_start); const PosixTransition& pt0(tt0->is_dst ? posix.dst_start : posix.dst_end); for (const cctz::year_t limit = last_year_ + 400; last_year_ < limit;) { last_year_ += 1; // an additional year of generated transitions jan1_time += kSecsPerYear[leap_year]; jan1_weekday = (jan1_weekday + kDaysPerYear[leap_year]) % 7; leap_year = !leap_year && IsLeap(last_year_); std::int_fast64_t tr1_offset = TransOffset(leap_year, jan1_weekday, pt1); tr->unix_time = jan1_time + tr1_offset - tt0->utc_offset; tr++->type_index = tr1->type_index; std::int_fast64_t tr0_offset = TransOffset(leap_year, jan1_weekday, pt0); tr->unix_time = jan1_time + tr0_offset - tt1->utc_offset; tr++->type_index = tr0->type_index; } assert(tr == &transitions_[0] + transitions_.size()); } bool TimeZoneInfo::Load(const std::string& name, ZoneInfoSource* zip) { // Read and validate the header. tzhead tzh; if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false; if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0) return false; Header hdr; if (!hdr.Build(tzh)) return false; std::size_t time_len = 4; if (tzh.tzh_version[0] != '\0') { // Skip the 4-byte data. if (zip->Skip(hdr.DataLength(time_len)) != 0) return false; // Read and validate the header for the 8-byte data. if (zip->Read(&tzh, sizeof(tzh)) != sizeof(tzh)) return false; if (strncmp(tzh.tzh_magic, TZ_MAGIC, sizeof(tzh.tzh_magic)) != 0) return false; if (tzh.tzh_version[0] == '\0') return false; if (!hdr.Build(tzh)) return false; time_len = 8; } if (hdr.typecnt == 0) return false; if (hdr.leapcnt != 0) { // This code assumes 60-second minutes so we do not want // the leap-second encoded zoneinfo. We could reverse the // compensation, but the "right" encoding is rarely used // so currently we simply reject such data. return false; } if (hdr.ttisstdcnt != 0 && hdr.ttisstdcnt != hdr.typecnt) return false; if (hdr.ttisgmtcnt != 0 && hdr.ttisgmtcnt != hdr.typecnt) return false; // Read the data into a local buffer. std::size_t len = hdr.DataLength(time_len); std::vector tbuf(len); if (zip->Read(tbuf.data(), len) != len) return false; const char* bp = tbuf.data(); // Decode and validate the transitions. transitions_.reserve(hdr.timecnt + 2); // We might add a couple. transitions_.resize(hdr.timecnt); for (std::size_t i = 0; i != hdr.timecnt; ++i) { transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp); bp += time_len; if (i != 0) { // Check that the transitions are ordered by time (as zic guarantees). if (!Transition::ByUnixTime()(transitions_[i - 1], transitions_[i])) return false; // out of order } } bool seen_type_0 = false; for (std::size_t i = 0; i != hdr.timecnt; ++i) { transitions_[i].type_index = Decode8(bp++); if (transitions_[i].type_index >= hdr.typecnt) return false; if (transitions_[i].type_index == 0) seen_type_0 = true; } // Decode and validate the transition types. transition_types_.resize(hdr.typecnt); for (std::size_t i = 0; i != hdr.typecnt; ++i) { transition_types_[i].utc_offset = static_cast(Decode32(bp)); if (transition_types_[i].utc_offset >= kSecsPerDay || transition_types_[i].utc_offset <= -kSecsPerDay) return false; bp += 4; transition_types_[i].is_dst = (Decode8(bp++) != 0); transition_types_[i].abbr_index = Decode8(bp++); if (transition_types_[i].abbr_index >= hdr.charcnt) return false; } // Determine the before-first-transition type. default_transition_type_ = 0; if (seen_type_0 && hdr.timecnt != 0) { std::uint_fast8_t index = 0; if (transition_types_[0].is_dst) { index = transitions_[0].type_index; while (index != 0 && transition_types_[index].is_dst) --index; } while (index != hdr.typecnt && transition_types_[index].is_dst) ++index; if (index != hdr.typecnt) default_transition_type_ = index; } // Copy all the abbreviations. abbreviations_.assign(bp, hdr.charcnt); bp += hdr.charcnt; // Skip the unused portions. We've already dispensed with leap-second // encoded zoneinfo. The ttisstd/ttisgmt indicators only apply when // interpreting a POSIX spec that does not include start/end rules, and // that isn't the case here (see "zic -p"). bp += (8 + 4) * hdr.leapcnt; // leap-time + TAI-UTC bp += 1 * hdr.ttisstdcnt; // UTC/local indicators bp += 1 * hdr.ttisgmtcnt; // standard/wall indicators assert(bp == tbuf.data() + tbuf.size()); future_spec_.clear(); if (tzh.tzh_version[0] != '\0') { // Snarf up the NL-enclosed future POSIX spec. Note // that version '3' files utilize an extended format. auto get_char = [](ZoneInfoSource* zip) -> int { unsigned char ch; // all non-EOF results are positive return (zip->Read(&ch, 1) == 1) ? ch : EOF; }; if (get_char(zip) != '\n') return false; for (int c = get_char(zip); c != '\n'; c = get_char(zip)) { if (c == EOF) return false; future_spec_.push_back(static_cast(c)); } } // We don't check for EOF so that we're forwards compatible. // Trim redundant transitions. zic may have added these to work around // differences between the glibc and reference implementations (see // zic.c:dontmerge) and the Qt library (see zic.c:WORK_AROUND_QTBUG_53071). // For us, they just get in the way when we do future_spec_ extension. while (hdr.timecnt > 1) { if (!EquivTransitions(transitions_[hdr.timecnt - 1].type_index, transitions_[hdr.timecnt - 2].type_index)) { break; } hdr.timecnt -= 1; } transitions_.resize(hdr.timecnt); // Ensure that there is always a transition in the first half of the // time line (the second half is handled in ExtendTransitions()) so that // the signed difference between a civil_second and the civil_second of // its previous transition is always representable, without overflow. // A contemporary zic will usually have already done this for us. if (transitions_.empty() || transitions_.front().unix_time >= 0) { Transition& tr(*transitions_.emplace(transitions_.begin())); tr.unix_time = -(1LL << 59); // see tz/zic.c "BIG_BANG" tr.type_index = default_transition_type_; hdr.timecnt += 1; } // Extend the transitions using the future specification. ExtendTransitions(name, hdr); // Compute the local civil time for each transition and the preceeding // second. These will be used for reverse conversions in MakeTime(). const TransitionType* ttp = &transition_types_[default_transition_type_]; for (std::size_t i = 0; i != transitions_.size(); ++i) { Transition& tr(transitions_[i]); tr.prev_civil_sec = LocalTime(tr.unix_time, *ttp).cs - 1; ttp = &transition_types_[tr.type_index]; tr.civil_sec = LocalTime(tr.unix_time, *ttp).cs; if (i != 0) { // Check that the transitions are ordered by civil time. Essentially // this means that an offset change cannot cross another such change. // No one does this in practice, and we depend on it in MakeTime(). if (!Transition::ByCivilTime()(transitions_[i - 1], tr)) return false; // out of order } } // Compute the maximum/minimum civil times that can be converted to a // time_point for each of the zone's transition types. for (auto& tt : transition_types_) { tt.civil_max = LocalTime(sys_seconds::max().count(), tt).cs; tt.civil_min = LocalTime(sys_seconds::min().count(), tt).cs; } transitions_.shrink_to_fit(); return true; } namespace { // A stdio(3)-backed implementation of ZoneInfoSource. class FileZoneInfoSource : public ZoneInfoSource { public: static std::unique_ptr Open(const std::string& name); std::size_t Read(void* ptr, std::size_t size) override { return fread(ptr, 1, size, fp_); } int Skip(std::size_t offset) override { return fseek(fp_, static_cast(offset), SEEK_CUR); } private: explicit FileZoneInfoSource(FILE* fp) : fp_(fp) {} ~FileZoneInfoSource() { fclose(fp_); } FILE* const fp_; }; std::unique_ptr FileZoneInfoSource::Open( const std::string& name) { // Use of the "file:" prefix is intended for testing purposes only. if (name.compare(0, 5, "file:") == 0) return Open(name.substr(5)); // Map the time-zone name to a path name. std::string path; if (name.empty() || name[0] != '/') { const char* tzdir = "/usr/share/zoneinfo"; char* tzdir_env = nullptr; #if defined(_MSC_VER) _dupenv_s(&tzdir_env, nullptr, "TZDIR"); #else tzdir_env = std::getenv("TZDIR"); #endif if (tzdir_env && *tzdir_env) tzdir = tzdir_env; path += tzdir; path += '/'; #if defined(_MSC_VER) free(tzdir_env); #endif } path += name; // Open the zoneinfo file. #if defined(_MSC_VER) FILE* fp; if (fopen_s(&fp, path.c_str(), "rb") != 0) fp = nullptr; #else FILE* fp = fopen(path.c_str(), "rb"); #endif if (fp == nullptr) return nullptr; return std::unique_ptr(new FileZoneInfoSource(fp)); } } // namespace bool TimeZoneInfo::Load(const std::string& name) { // We can ensure that the loading of UTC or any other fixed-offset // zone never fails because the simple, fixed-offset state can be // internally generated. Note that this depends on our choice to not // accept leap-second encoded ("right") zoneinfo. auto offset = sys_seconds::zero(); if (FixedOffsetFromName(name, &offset)) { return ResetToBuiltinUTC(offset); } // Find and use a ZoneInfoSource to load the named zone. auto zip = cctz_extension::zone_info_source_factory( name, [](const std::string& name) { return FileZoneInfoSource::Open(name); // fallback factory }); return zip != nullptr && Load(name, zip.get()); } // BreakTime() translation for a particular transition type. time_zone::absolute_lookup TimeZoneInfo::LocalTime( std::int_fast64_t unix_time, const TransitionType& tt) const { time_zone::absolute_lookup al; // A civil time in "+offset" looks like (time+offset) in UTC. // Note: We perform two additions in the civil_second domain to // sidestep the chance of overflow in (unix_time + tt.utc_offset). al.cs = (civil_second() + unix_time) + tt.utc_offset; // Handle offset, is_dst, and abbreviation. al.offset = tt.utc_offset; al.is_dst = tt.is_dst; al.abbr = &abbreviations_[tt.abbr_index]; return al; } // MakeTime() translation with a conversion-preserving +N * 400-year shift. time_zone::civil_lookup TimeZoneInfo::TimeLocal(const civil_second& cs, cctz::year_t c4_shift) const { assert(last_year_ - 400 < cs.year() && cs.year() <= last_year_); time_zone::civil_lookup cl = MakeTime(cs); if (c4_shift > sys_seconds::max().count() / kSecsPer400Years) { cl.pre = cl.trans = cl.post = time_point::max(); } else { const auto offset = sys_seconds(c4_shift * kSecsPer400Years); const auto limit = time_point::max() - offset; for (auto* tp : {&cl.pre, &cl.trans, &cl.post}) { if (*tp > limit) { *tp = time_point::max(); } else { *tp += offset; } } } return cl; } time_zone::absolute_lookup TimeZoneInfo::BreakTime( const time_point& tp) const { std::int_fast64_t unix_time = ToUnixSeconds(tp); const std::size_t timecnt = transitions_.size(); if (timecnt == 0 || unix_time < transitions_[0].unix_time) { const std::uint_fast8_t type_index = default_transition_type_; return LocalTime(unix_time, transition_types_[type_index]); } if (unix_time >= transitions_[timecnt - 1].unix_time) { // After the last transition. If we extended the transitions using // future_spec_, shift back to a supported year using the 400-year // cycle of calendaric equivalence and then compensate accordingly. if (extended_) { const std::int_fast64_t diff = unix_time - transitions_[timecnt - 1].unix_time; const cctz::year_t shift = diff / kSecsPer400Years + 1; const auto d = sys_seconds(shift * kSecsPer400Years); time_zone::absolute_lookup al = BreakTime(tp - d); al.cs = YearShift(al.cs, shift * 400); return al; } const std::uint_fast8_t type_index = transitions_[timecnt - 1].type_index; return LocalTime(unix_time, transition_types_[type_index]); } const std::size_t hint = local_time_hint_.load(std::memory_order_relaxed); if (0 < hint && hint < timecnt) { if (unix_time < transitions_[hint].unix_time) { if (!(unix_time < transitions_[hint - 1].unix_time)) { const std::uint_fast8_t type_index = transitions_[hint - 1].type_index; return LocalTime(unix_time, transition_types_[type_index]); } } } const Transition target = {unix_time, 0, civil_second(), civil_second()}; const Transition* begin = &transitions_[0]; const Transition* tr = std::upper_bound(begin, begin + timecnt, target, Transition::ByUnixTime()); local_time_hint_.store(static_cast(tr - begin), std::memory_order_relaxed); const std::uint_fast8_t type_index = (--tr)->type_index; return LocalTime(unix_time, transition_types_[type_index]); } time_zone::civil_lookup TimeZoneInfo::MakeTime(const civil_second& cs) const { const std::size_t timecnt = transitions_.size(); assert(timecnt != 0); // We always add a transition. // Find the first transition after our target civil time. const Transition* tr = nullptr; const Transition* begin = &transitions_[0]; const Transition* end = begin + timecnt; if (cs < begin->civil_sec) { tr = begin; } else if (!(cs < transitions_[timecnt - 1].civil_sec)) { tr = end; } else { const std::size_t hint = time_local_hint_.load(std::memory_order_relaxed); if (0 < hint && hint < timecnt) { if (cs < transitions_[hint].civil_sec) { if (!(cs < transitions_[hint - 1].civil_sec)) { tr = begin + hint; } } } if (tr == nullptr) { const Transition target = {0, 0, cs, civil_second()}; tr = std::upper_bound(begin, end, target, Transition::ByCivilTime()); time_local_hint_.store(static_cast(tr - begin), std::memory_order_relaxed); } } if (tr == begin) { if (!(tr->prev_civil_sec < cs)) { // Before first transition, so use the default offset. const TransitionType& tt(transition_types_[default_transition_type_]); if (cs < tt.civil_min) return MakeUnique(time_point::min()); return MakeUnique(cs - (civil_second() + tt.utc_offset)); } // tr->prev_civil_sec < cs < tr->civil_sec return MakeSkipped(*tr, cs); } if (tr == end) { if ((--tr)->prev_civil_sec < cs) { // After the last transition. If we extended the transitions using // future_spec_, shift back to a supported year using the 400-year // cycle of calendaric equivalence and then compensate accordingly. if (extended_ && cs.year() > last_year_) { const cctz::year_t shift = (cs.year() - last_year_ - 1) / 400 + 1; return TimeLocal(YearShift(cs, shift * -400), shift); } const TransitionType& tt(transition_types_[tr->type_index]); if (cs > tt.civil_max) return MakeUnique(time_point::max()); return MakeUnique(tr->unix_time + (cs - tr->civil_sec)); } // tr->civil_sec <= cs <= tr->prev_civil_sec return MakeRepeated(*tr, cs); } if (tr->prev_civil_sec < cs) { // tr->prev_civil_sec < cs < tr->civil_sec return MakeSkipped(*tr, cs); } if (!((--tr)->prev_civil_sec < cs)) { // tr->civil_sec <= cs <= tr->prev_civil_sec return MakeRepeated(*tr, cs); } // In between transitions. return MakeUnique(tr->unix_time + (cs - tr->civil_sec)); } std::string TimeZoneInfo::Description() const { std::ostringstream oss; // TODO: It would nice if the zoneinfo data included the zone name. // TODO: It would nice if the zoneinfo data included the tzdb version. oss << "#trans=" << transitions_.size(); oss << " #types=" << transition_types_.size(); oss << " spec='" << future_spec_ << "'"; return oss.str(); } bool TimeZoneInfo::NextTransition(time_point* tp) const { if (transitions_.empty()) return false; const Transition* begin = &transitions_[0]; const Transition* end = begin + transitions_.size(); if (begin->unix_time <= -(1LL << 59)) { // Do not report the BIG_BANG found in recent zoneinfo data as it is // really a sentinel, not a transition. See third_party/tz/zic.c. ++begin; } std::int_fast64_t unix_time = ToUnixSeconds(*tp); const Transition target = { unix_time }; const Transition* tr = std::upper_bound(begin, end, target, Transition::ByUnixTime()); if (tr != begin) { // skip no-op transitions for (; tr != end; ++tr) { if (!EquivTransitions(tr[-1].type_index, tr[0].type_index)) break; } } // When tr == end we return false, ignoring future_spec_. if (tr == end) return false; *tp = FromUnixSeconds(tr->unix_time); return true; } bool TimeZoneInfo::PrevTransition(time_point* tp) const { if (transitions_.empty()) return false; const Transition* begin = &transitions_[0]; const Transition* end = begin + transitions_.size(); if (begin->unix_time <= -(1LL << 59)) { // Do not report the BIG_BANG found in recent zoneinfo data as it is // really a sentinel, not a transition. See third_party/tz/zic.c. ++begin; } std::int_fast64_t unix_time = ToUnixSeconds(*tp); if (FromUnixSeconds(unix_time) != *tp) { if (unix_time == std::numeric_limits::max()) { if (end == begin) return false; // Ignore future_spec_. *tp = FromUnixSeconds((--end)->unix_time); return true; } unix_time += 1; // ceils } const Transition target = { unix_time }; const Transition* tr = std::lower_bound(begin, end, target, Transition::ByUnixTime()); if (tr != begin) { // skip no-op transitions for (; tr - 1 != begin; --tr) { if (!EquivTransitions(tr[-2].type_index, tr[-1].type_index)) break; } } // When tr == end we return the "last" transition, ignoring future_spec_. if (tr == begin) return false; *tp = FromUnixSeconds((--tr)->unix_time); return true; } } // namespace cctz lubridate/src/cctz/src/time_zone_fixed.cc0000644000176200001440000001027713263152652020241 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "time_zone_fixed.h" #include #include #include #include #include namespace cctz { namespace { // The prefix used for the internal names of fixed-offset zones. const char kFixedOffsetPrefix[] = "Fixed/"; int Parse02d(const char* p) { const char kDigits[] = "0123456789"; if (const char* ap = std::strchr(kDigits, *p)) { int v = static_cast(ap - kDigits); if (const char* bp = std::strchr(kDigits, *++p)) { return (v * 10) + static_cast(bp - kDigits); } } return -1; } } // namespace bool FixedOffsetFromName(const std::string& name, sys_seconds* offset) { if (name.compare(0, std::string::npos, "UTC", 3) == 0) { *offset = sys_seconds::zero(); return true; } const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1; const char* const ep = kFixedOffsetPrefix + prefix_len; if (name.size() != prefix_len + 12) // "UTC+99:99:99" return false; if (!std::equal(kFixedOffsetPrefix, ep, name.begin())) return false; const char* np = name.data() + prefix_len; if (*np++ != 'U' || *np++ != 'T' || *np++ != 'C') return false; if (np[0] != '+' && np[0] != '-') return false; if (np[3] != ':' || np[6] != ':') // see note below about large offsets return false; int hours = Parse02d(np + 1); if (hours == -1) return false; int mins = Parse02d(np + 4); if (mins == -1) return false; int secs = Parse02d(np + 7); if (secs == -1) return false; secs += ((hours * 60) + mins) * 60; if (secs > 24 * 60 * 60) return false; // outside supported offset range *offset = sys_seconds(secs * (np[0] == '-' ? -1 : 1)); // "-" means west return true; } std::string FixedOffsetToName(const sys_seconds& offset) { if (offset == sys_seconds::zero()) return "UTC"; if (offset < std::chrono::hours(-24) || offset > std::chrono::hours(24)) { // We don't support fixed-offset zones more than 24 hours // away from UTC to avoid complications in rendering such // offsets and to (somewhat) limit the total number of zones. return "UTC"; } int seconds = static_cast(offset.count()); const char sign = (seconds < 0 ? '-' : '+'); int minutes = seconds / 60; seconds %= 60; if (sign == '-') { if (seconds > 0) { seconds -= 60; minutes += 1; } seconds = -seconds; minutes = -minutes; } int hours = minutes / 60; minutes %= 60; char buf[sizeof(kFixedOffsetPrefix) + sizeof("UTC-24:00:00")]; snprintf(buf, sizeof(buf), "%sUTC%c%02d:%02d:%02d", kFixedOffsetPrefix, sign, hours, minutes, seconds); return buf; } std::string FixedOffsetToAbbr(const sys_seconds& offset) { std::string abbr = FixedOffsetToName(offset); const std::size_t prefix_len = sizeof(kFixedOffsetPrefix) - 1; const char* const ep = kFixedOffsetPrefix + prefix_len; if (abbr.size() >= prefix_len) { if (std::equal(kFixedOffsetPrefix, ep, abbr.begin())) { abbr.erase(0, prefix_len); if (abbr.size() == 12) { // UTC+99:99:99 abbr.erase(9, 1); // UTC+99:9999 abbr.erase(6, 1); // UTC+999999 if (abbr[8] == '0' && abbr[9] == '0') { // UTC+999900 abbr.erase(8, 2); // UTC+9999 if (abbr[6] == '0' && abbr[7] == '0') { // UTC+9900 abbr.erase(6, 2); // UTC+99 if (abbr[4] == '0') { // UTC+09 abbr.erase(4, 1); // UTC+9 } } } } } } return abbr; } } // namespace cctz lubridate/src/cctz/src/time_zone_if.cc0000644000176200001440000000236213263152652017534 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "time_zone_if.h" #include "time_zone_info.h" #include "time_zone_libc.h" namespace cctz { std::unique_ptr TimeZoneIf::Load(const std::string& name) { // Support "libc:localtime" and "libc:*" to access the legacy // localtime and UTC support respectively from the C library. if (name.compare(0, 5, "libc:") == 0) { return std::unique_ptr(new TimeZoneLibC(name.substr(5))); } // Otherwise use the "zoneinfo" implementation by default. std::unique_ptr tz(new TimeZoneInfo); if (!tz->Load(name)) tz.reset(); return std::unique_ptr(tz.release()); } } // namespace cctz lubridate/src/cctz/src/time_zone_lookup_test.cc0000644000176200001440000011451413263152652021511 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "time_zone.h" #include #include #include #include #include #include #include "civil_time.h" #include "gtest/gtest.h" using std::chrono::time_point_cast; using std::chrono::system_clock; using std::chrono::nanoseconds; using std::chrono::microseconds; using std::chrono::milliseconds; using std::chrono::seconds; using std::chrono::minutes; using std::chrono::hours; namespace cctz { namespace { // A list of known time-zone names. const char* const kTimeZoneNames[] = { "Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa", "Africa/Algiers", "Africa/Asmara", "Africa/Asmera", "Africa/Bamako", "Africa/Bangui", "Africa/Banjul", "Africa/Bissau", "Africa/Blantyre", "Africa/Brazzaville", "Africa/Bujumbura", "Africa/Cairo", "Africa/Casablanca", "Africa/Ceuta", "Africa/Conakry", "Africa/Dakar", "Africa/Dar_es_Salaam", "Africa/Djibouti", "Africa/Douala", "Africa/El_Aaiun", "Africa/Freetown", "Africa/Gaborone", "Africa/Harare", "Africa/Johannesburg", "Africa/Juba", "Africa/Kampala", "Africa/Khartoum", "Africa/Kigali", "Africa/Kinshasa", "Africa/Lagos", "Africa/Libreville", "Africa/Lome", "Africa/Luanda", "Africa/Lubumbashi", "Africa/Lusaka", "Africa/Malabo", "Africa/Maputo", "Africa/Maseru", "Africa/Mbabane", "Africa/Mogadishu", "Africa/Monrovia", "Africa/Nairobi", "Africa/Ndjamena", "Africa/Niamey", "Africa/Nouakchott", "Africa/Ouagadougou", "Africa/Porto-Novo", "Africa/Sao_Tome", "Africa/Timbuktu", "Africa/Tripoli", "Africa/Tunis", "Africa/Windhoek", "America/Adak", "America/Anchorage", "America/Anguilla", "America/Antigua", "America/Araguaina", "America/Argentina/Buenos_Aires", "America/Argentina/Catamarca", "America/Argentina/ComodRivadavia", "America/Argentina/Cordoba", "America/Argentina/Jujuy", "America/Argentina/La_Rioja", "America/Argentina/Mendoza", "America/Argentina/Rio_Gallegos", "America/Argentina/Salta", "America/Argentina/San_Juan", "America/Argentina/San_Luis", "America/Argentina/Tucuman", "America/Argentina/Ushuaia", "America/Aruba", "America/Asuncion", "America/Atikokan", "America/Atka", "America/Bahia", "America/Bahia_Banderas", "America/Barbados", "America/Belem", "America/Belize", "America/Blanc-Sablon", "America/Boa_Vista", "America/Bogota", "America/Boise", "America/Buenos_Aires", "America/Cambridge_Bay", "America/Campo_Grande", "America/Cancun", "America/Caracas", "America/Catamarca", "America/Cayenne", "America/Cayman", "America/Chicago", "America/Chihuahua", "America/Coral_Harbour", "America/Cordoba", "America/Costa_Rica", "America/Creston", "America/Cuiaba", "America/Curacao", "America/Danmarkshavn", "America/Dawson", "America/Dawson_Creek", "America/Denver", "America/Detroit", "America/Dominica", "America/Edmonton", "America/Eirunepe", "America/El_Salvador", "America/Ensenada", "America/Fort_Nelson", "America/Fort_Wayne", "America/Fortaleza", "America/Glace_Bay", "America/Godthab", "America/Goose_Bay", "America/Grand_Turk", "America/Grenada", "America/Guadeloupe", "America/Guatemala", "America/Guayaquil", "America/Guyana", "America/Halifax", "America/Havana", "America/Hermosillo", "America/Indiana/Indianapolis", "America/Indiana/Knox", "America/Indiana/Marengo", "America/Indiana/Petersburg", "America/Indiana/Tell_City", "America/Indiana/Vevay", "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Indianapolis", "America/Inuvik", "America/Iqaluit", "America/Jamaica", "America/Jujuy", "America/Juneau", "America/Kentucky/Louisville", "America/Kentucky/Monticello", "America/Knox_IN", "America/Kralendijk", "America/La_Paz", "America/Lima", "America/Los_Angeles", "America/Louisville", "America/Lower_Princes", "America/Maceio", "America/Managua", "America/Manaus", "America/Marigot", "America/Martinique", "America/Matamoros", "America/Mazatlan", "America/Mendoza", "America/Menominee", "America/Merida", "America/Metlakatla", "America/Mexico_City", "America/Miquelon", "America/Moncton", "America/Monterrey", "America/Montevideo", "America/Montreal", "America/Montserrat", "America/Nassau", "America/New_York", "America/Nipigon", "America/Nome", "America/Noronha", "America/North_Dakota/Beulah", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", "America/Ojinaga", "America/Panama", "America/Pangnirtung", "America/Paramaribo", "America/Phoenix", "America/Port-au-Prince", "America/Port_of_Spain", "America/Porto_Acre", "America/Porto_Velho", "America/Puerto_Rico", "America/Punta_Arenas", "America/Rainy_River", "America/Rankin_Inlet", "America/Recife", "America/Regina", "America/Resolute", "America/Rio_Branco", "America/Rosario", "America/Santa_Isabel", "America/Santarem", "America/Santiago", "America/Santo_Domingo", "America/Sao_Paulo", "America/Scoresbysund", "America/Shiprock", "America/Sitka", "America/St_Barthelemy", "America/St_Johns", "America/St_Kitts", "America/St_Lucia", "America/St_Thomas", "America/St_Vincent", "America/Swift_Current", "America/Tegucigalpa", "America/Thule", "America/Thunder_Bay", "America/Tijuana", "America/Toronto", "America/Tortola", "America/Vancouver", "America/Virgin", "America/Whitehorse", "America/Winnipeg", "America/Yakutat", "America/Yellowknife", "Antarctica/Casey", "Antarctica/Davis", "Antarctica/DumontDUrville", "Antarctica/Macquarie", "Antarctica/Mawson", "Antarctica/McMurdo", "Antarctica/Palmer", "Antarctica/Rothera", "Antarctica/South_Pole", "Antarctica/Syowa", "Antarctica/Troll", "Antarctica/Vostok", "Arctic/Longyearbyen", "Asia/Aden", "Asia/Almaty", "Asia/Amman", "Asia/Anadyr", "Asia/Aqtau", "Asia/Aqtobe", "Asia/Ashgabat", "Asia/Ashkhabad", "Asia/Atyrau", "Asia/Baghdad", "Asia/Bahrain", "Asia/Baku", "Asia/Bangkok", "Asia/Barnaul", "Asia/Beirut", "Asia/Bishkek", "Asia/Brunei", "Asia/Calcutta", "Asia/Chita", "Asia/Choibalsan", "Asia/Chongqing", "Asia/Chungking", "Asia/Colombo", "Asia/Dacca", "Asia/Damascus", "Asia/Dhaka", "Asia/Dili", "Asia/Dubai", "Asia/Dushanbe", "Asia/Famagusta", "Asia/Gaza", "Asia/Harbin", "Asia/Hebron", "Asia/Ho_Chi_Minh", "Asia/Hong_Kong", "Asia/Hovd", "Asia/Irkutsk", "Asia/Istanbul", "Asia/Jakarta", "Asia/Jayapura", "Asia/Jerusalem", "Asia/Kabul", "Asia/Kamchatka", "Asia/Karachi", "Asia/Kashgar", "Asia/Kathmandu", "Asia/Katmandu", "Asia/Khandyga", "Asia/Kolkata", "Asia/Krasnoyarsk", "Asia/Kuala_Lumpur", "Asia/Kuching", "Asia/Kuwait", "Asia/Macao", "Asia/Macau", "Asia/Magadan", "Asia/Makassar", "Asia/Manila", "Asia/Muscat", "Asia/Nicosia", "Asia/Novokuznetsk", "Asia/Novosibirsk", "Asia/Omsk", "Asia/Oral", "Asia/Phnom_Penh", "Asia/Pontianak", "Asia/Pyongyang", "Asia/Qatar", "Asia/Qyzylorda", "Asia/Rangoon", "Asia/Riyadh", "Asia/Saigon", "Asia/Sakhalin", "Asia/Samarkand", "Asia/Seoul", "Asia/Shanghai", "Asia/Singapore", "Asia/Srednekolymsk", "Asia/Taipei", "Asia/Tashkent", "Asia/Tbilisi", "Asia/Tehran", "Asia/Tel_Aviv", "Asia/Thimbu", "Asia/Thimphu", "Asia/Tokyo", "Asia/Tomsk", "Asia/Ujung_Pandang", "Asia/Ulaanbaatar", "Asia/Ulan_Bator", "Asia/Urumqi", "Asia/Ust-Nera", "Asia/Vientiane", "Asia/Vladivostok", "Asia/Yakutsk", "Asia/Yangon", "Asia/Yekaterinburg", "Asia/Yerevan", "Atlantic/Azores", "Atlantic/Bermuda", "Atlantic/Canary", "Atlantic/Cape_Verde", "Atlantic/Faeroe", "Atlantic/Faroe", "Atlantic/Jan_Mayen", "Atlantic/Madeira", "Atlantic/Reykjavik", "Atlantic/South_Georgia", "Atlantic/St_Helena", "Atlantic/Stanley", "Australia/ACT", "Australia/Adelaide", "Australia/Brisbane", "Australia/Broken_Hill", "Australia/Canberra", "Australia/Currie", "Australia/Darwin", "Australia/Eucla", "Australia/Hobart", "Australia/LHI", "Australia/Lindeman", "Australia/Lord_Howe", "Australia/Melbourne", "Australia/NSW", "Australia/North", "Australia/Perth", "Australia/Queensland", "Australia/South", "Australia/Sydney", "Australia/Tasmania", "Australia/Victoria", "Australia/West", "Australia/Yancowinna", "Brazil/Acre", "Brazil/DeNoronha", "Brazil/East", "Brazil/West", "CET", "CST6CDT", "Canada/Atlantic", "Canada/Central", "Canada/East-Saskatchewan", "Canada/Eastern", "Canada/Mountain", "Canada/Newfoundland", "Canada/Pacific", "Canada/Saskatchewan", "Canada/Yukon", "Chile/Continental", "Chile/EasterIsland", "Cuba", "EET", "EST", "EST5EDT", "Egypt", "Eire", "Etc/GMT", "Etc/GMT+0", "Etc/GMT+1", "Etc/GMT+10", "Etc/GMT+11", "Etc/GMT+12", "Etc/GMT+2", "Etc/GMT+3", "Etc/GMT+4", "Etc/GMT+5", "Etc/GMT+6", "Etc/GMT+7", "Etc/GMT+8", "Etc/GMT+9", "Etc/GMT-0", "Etc/GMT-1", "Etc/GMT-10", "Etc/GMT-11", "Etc/GMT-12", "Etc/GMT-13", "Etc/GMT-14", "Etc/GMT-2", "Etc/GMT-3", "Etc/GMT-4", "Etc/GMT-5", "Etc/GMT-6", "Etc/GMT-7", "Etc/GMT-8", "Etc/GMT-9", "Etc/GMT0", "Etc/Greenwich", "Etc/UCT", "Etc/UTC", "Etc/Universal", "Etc/Zulu", "Europe/Amsterdam", "Europe/Andorra", "Europe/Astrakhan", "Europe/Athens", "Europe/Belfast", "Europe/Belgrade", "Europe/Berlin", "Europe/Bratislava", "Europe/Brussels", "Europe/Bucharest", "Europe/Budapest", "Europe/Busingen", "Europe/Chisinau", "Europe/Copenhagen", "Europe/Dublin", "Europe/Gibraltar", "Europe/Guernsey", "Europe/Helsinki", "Europe/Isle_of_Man", "Europe/Istanbul", "Europe/Jersey", "Europe/Kaliningrad", "Europe/Kiev", "Europe/Kirov", "Europe/Lisbon", "Europe/Ljubljana", "Europe/London", "Europe/Luxembourg", "Europe/Madrid", "Europe/Malta", "Europe/Mariehamn", "Europe/Minsk", "Europe/Monaco", "Europe/Moscow", "Europe/Nicosia", "Europe/Oslo", "Europe/Paris", "Europe/Podgorica", "Europe/Prague", "Europe/Riga", "Europe/Rome", "Europe/Samara", "Europe/San_Marino", "Europe/Sarajevo", "Europe/Saratov", "Europe/Simferopol", "Europe/Skopje", "Europe/Sofia", "Europe/Stockholm", "Europe/Tallinn", "Europe/Tirane", "Europe/Tiraspol", "Europe/Ulyanovsk", "Europe/Uzhgorod", "Europe/Vaduz", "Europe/Vatican", "Europe/Vienna", "Europe/Vilnius", "Europe/Volgograd", "Europe/Warsaw", "Europe/Zagreb", "Europe/Zaporozhye", "Europe/Zurich", "GB", "GB-Eire", "GMT", "GMT+0", "GMT-0", "GMT0", "Greenwich", "HST", "Hongkong", "Iceland", "Indian/Antananarivo", "Indian/Chagos", "Indian/Christmas", "Indian/Cocos", "Indian/Comoro", "Indian/Kerguelen", "Indian/Mahe", "Indian/Maldives", "Indian/Mauritius", "Indian/Mayotte", "Indian/Reunion", "Iran", "Israel", "Jamaica", "Japan", "Kwajalein", "Libya", "MET", "MST", "MST7MDT", "Mexico/BajaNorte", "Mexico/BajaSur", "Mexico/General", "NZ", "NZ-CHAT", "Navajo", "PRC", "PST8PDT", "Pacific/Apia", "Pacific/Auckland", "Pacific/Bougainville", "Pacific/Chatham", "Pacific/Chuuk", "Pacific/Easter", "Pacific/Efate", "Pacific/Enderbury", "Pacific/Fakaofo", "Pacific/Fiji", "Pacific/Funafuti", "Pacific/Galapagos", "Pacific/Gambier", "Pacific/Guadalcanal", "Pacific/Guam", "Pacific/Honolulu", "Pacific/Johnston", "Pacific/Kiritimati", "Pacific/Kosrae", "Pacific/Kwajalein", "Pacific/Majuro", "Pacific/Marquesas", "Pacific/Midway", "Pacific/Nauru", "Pacific/Niue", "Pacific/Norfolk", "Pacific/Noumea", "Pacific/Pago_Pago", "Pacific/Palau", "Pacific/Pitcairn", "Pacific/Pohnpei", "Pacific/Ponape", "Pacific/Port_Moresby", "Pacific/Rarotonga", "Pacific/Saipan", "Pacific/Samoa", "Pacific/Tahiti", "Pacific/Tarawa", "Pacific/Tongatapu", "Pacific/Truk", "Pacific/Wake", "Pacific/Wallis", "Pacific/Yap", "Poland", "Portugal", "ROC", "ROK", "Singapore", "Turkey", "UCT", "US/Alaska", "US/Aleutian", "US/Arizona", "US/Central", "US/East-Indiana", "US/Eastern", "US/Hawaii", "US/Indiana-Starke", "US/Michigan", "US/Mountain", "US/Pacific", "US/Pacific-New", "US/Samoa", "UTC", "Universal", "W-SU", "WET", "Zulu", nullptr }; // Helper to return a loaded time zone by value (UTC on error). time_zone LoadZone(const std::string& name) { time_zone tz; load_time_zone(name, &tz); return tz; } // This helper is a macro so that failed expectations show up with the // correct line numbers. #define ExpectTime(tp, tz, y, m, d, hh, mm, ss, off, isdst, zone) \ do { \ time_zone::absolute_lookup al = tz.lookup(tp); \ EXPECT_EQ(y, al.cs.year()); \ EXPECT_EQ(m, al.cs.month()); \ EXPECT_EQ(d, al.cs.day()); \ EXPECT_EQ(hh, al.cs.hour()); \ EXPECT_EQ(mm, al.cs.minute()); \ EXPECT_EQ(ss, al.cs.second()); \ EXPECT_EQ(off, al.offset); \ EXPECT_TRUE(isdst == al.is_dst); \ /* EXPECT_STREQ(zone, al.abbr); */ \ } while (0) } // namespace TEST(TimeZones, LoadZonesConcurrently) { std::promise ready_promise; std::shared_future ready_future(ready_promise.get_future()); auto load_zones = [ready_future](std::promise* started, std::set* failures) { started->set_value(); ready_future.wait(); for (const char* const* np = kTimeZoneNames; *np != nullptr; ++np) { std::string zone = *np; time_zone tz; if (load_time_zone(zone, &tz)) { EXPECT_EQ(zone, tz.name()); } else { failures->insert(zone); } } }; const std::size_t n_threads = 256; std::vector threads; std::vector> thread_failures(n_threads); for (std::size_t i = 0; i != n_threads; ++i) { std::promise started; threads.emplace_back(load_zones, &started, &thread_failures[i]); started.get_future().wait(); } ready_promise.set_value(); for (auto& thread : threads) { thread.join(); } // Allow a small number of failures to account for skew between // the contents of kTimeZoneNames and the zoneinfo data source. const std::size_t max_failures = 3; std::set failures; for (const auto& thread_failure : thread_failures) { failures.insert(thread_failure.begin(), thread_failure.end()); } EXPECT_LE(failures.size(), max_failures) << testing::PrintToString(failures); } TEST(TimeZone, NamedTimeZones) { const time_zone utc = utc_time_zone(); EXPECT_EQ("UTC", utc.name()); const time_zone nyc = LoadZone("America/New_York"); EXPECT_EQ("America/New_York", nyc.name()); const time_zone syd = LoadZone("Australia/Sydney"); EXPECT_EQ("Australia/Sydney", syd.name()); const time_zone fixed0 = fixed_time_zone(sys_seconds::zero()); EXPECT_EQ("UTC", fixed0.name()); const time_zone fixed_pos = fixed_time_zone(hours(3) + minutes(25) + seconds(45)); EXPECT_EQ("Fixed/UTC+03:25:45", fixed_pos.name()); const time_zone fixed_neg = fixed_time_zone(-(hours(12) + minutes(34) + seconds(56))); EXPECT_EQ("Fixed/UTC-12:34:56", fixed_neg.name()); } TEST(TimeZone, Failures) { time_zone tz; EXPECT_FALSE(load_time_zone(":America/Los_Angeles", &tz)); tz = LoadZone("America/Los_Angeles"); EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &tz)); EXPECT_EQ(system_clock::from_time_t(0), convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC // Ensures that the load still fails on a subsequent attempt. tz = LoadZone("America/Los_Angeles"); EXPECT_FALSE(load_time_zone("Invalid/TimeZone", &tz)); EXPECT_EQ(system_clock::from_time_t(0), convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC // Loading an empty string timezone should fail. tz = LoadZone("America/Los_Angeles"); EXPECT_FALSE(load_time_zone("", &tz)); EXPECT_EQ(system_clock::from_time_t(0), convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC } TEST(TimeZone, Equality) { const time_zone a; const time_zone b; EXPECT_EQ(a, b); EXPECT_EQ(a.name(), b.name()); const time_zone implicit_utc; const time_zone explicit_utc = utc_time_zone(); EXPECT_EQ(implicit_utc, explicit_utc); EXPECT_EQ(implicit_utc.name(), explicit_utc.name()); const time_zone fixed_zero = fixed_time_zone(sys_seconds::zero()); EXPECT_EQ(fixed_zero, LoadZone(fixed_zero.name())); EXPECT_EQ(fixed_zero, explicit_utc); const time_zone fixed_utc = LoadZone("Fixed/UTC+00:00:00"); EXPECT_EQ(fixed_utc, LoadZone(fixed_utc.name())); EXPECT_EQ(fixed_utc, explicit_utc); const time_zone fixed_pos = fixed_time_zone(hours(3) + minutes(25) + seconds(45)); EXPECT_EQ(fixed_pos, LoadZone(fixed_pos.name())); EXPECT_NE(fixed_pos, explicit_utc); const time_zone fixed_neg = fixed_time_zone(-(hours(12) + minutes(34) + seconds(56))); EXPECT_EQ(fixed_neg, LoadZone(fixed_neg.name())); EXPECT_NE(fixed_neg, explicit_utc); const time_zone fixed_lim = fixed_time_zone(hours(24)); EXPECT_EQ(fixed_lim, LoadZone(fixed_lim.name())); EXPECT_NE(fixed_lim, explicit_utc); const time_zone fixed_ovfl = fixed_time_zone(hours(24) + seconds(1)); EXPECT_EQ(fixed_ovfl, LoadZone(fixed_ovfl.name())); EXPECT_EQ(fixed_ovfl, explicit_utc); EXPECT_EQ(fixed_time_zone(seconds(1)), fixed_time_zone(seconds(1))); const time_zone local = local_time_zone(); EXPECT_EQ(local, LoadZone(local.name())); time_zone la = LoadZone("America/Los_Angeles"); time_zone nyc = LoadZone("America/New_York"); EXPECT_NE(la, nyc); } TEST(StdChronoTimePoint, TimeTAlignment) { // Ensures that the Unix epoch and the system clock epoch are an integral // number of seconds apart. This simplifies conversions to/from time_t. auto diff = system_clock::time_point() - system_clock::from_time_t(0); EXPECT_EQ(system_clock::time_point::duration::zero(), diff % seconds(1)); } TEST(BreakTime, TimePointResolution) { const time_zone utc = utc_time_zone(); const auto t0 = system_clock::from_time_t(0); ExpectTime(time_point_cast(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); ExpectTime(time_point_cast(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); ExpectTime(time_point_cast(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); ExpectTime(time_point_cast(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); ExpectTime(time_point_cast(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); ExpectTime(time_point_cast(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); ExpectTime(time_point_cast(t0), utc, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); } TEST(BreakTime, LocalTimeInUTC) { const time_zone tz = utc_time_zone(); const auto tp = system_clock::from_time_t(0); ExpectTime(tp, tz, 1970, 1, 1, 0, 0, 0, 0, false, "UTC"); EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); } TEST(BreakTime, LocalTimeInUTCUnaligned) { const time_zone tz = utc_time_zone(); const auto tp = system_clock::from_time_t(0) - milliseconds(500); ExpectTime(tp, tz, 1969, 12, 31, 23, 59, 59, 0, false, "UTC"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); } TEST(BreakTime, LocalTimePosix) { // See IEEE Std 1003.1-1988 B.2.3 General Terms, Epoch. const time_zone tz = utc_time_zone(); const auto tp = system_clock::from_time_t(536457599); ExpectTime(tp, tz, 1986, 12, 31, 23, 59, 59, 0, false, "UTC"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); } TEST(TimeZoneImpl, LocalTimeInFixed) { const sys_seconds offset = -(hours(8) + minutes(33) + seconds(47)); const time_zone tz = fixed_time_zone(offset); const auto tp = system_clock::from_time_t(0); ExpectTime(tp, tz, 1969, 12, 31, 15, 26, 13, offset.count(), false, "UTC-083347"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); } TEST(BreakTime, LocalTimeInNewYork) { const time_zone tz = LoadZone("America/New_York"); const auto tp = system_clock::from_time_t(45); ExpectTime(tp, tz, 1969, 12, 31, 19, 0, 45, -5 * 60 * 60, false, "EST"); EXPECT_EQ(weekday::wednesday, get_weekday(civil_day(convert(tp, tz)))); } TEST(BreakTime, LocalTimeInMTV) { const time_zone tz = LoadZone("America/Los_Angeles"); const auto tp = system_clock::from_time_t(1380855729); ExpectTime(tp, tz, 2013, 10, 3, 20, 2, 9, -7 * 60 * 60, true, "PDT"); EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); } TEST(BreakTime, LocalTimeInSydney) { const time_zone tz = LoadZone("Australia/Sydney"); const auto tp = system_clock::from_time_t(90); ExpectTime(tp, tz, 1970, 1, 1, 10, 1, 30, 10 * 60 * 60, false, "AEST"); EXPECT_EQ(weekday::thursday, get_weekday(civil_day(convert(tp, tz)))); } TEST(MakeTime, TimePointResolution) { const time_zone utc = utc_time_zone(); const time_point tp_ns = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_ns, utc)); const time_point tp_us = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_us, utc)); const time_point tp_ms = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_ms, utc)); const time_point tp_s = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_s, utc)); const time_point tp_s64 = convert(civil_second(2015, 1, 2, 3, 4, 5), utc); EXPECT_EQ("04:05", format("%M:%E*S", tp_s64, utc)); // These next two require time_point_cast because the conversion from a // resolution of seconds (the return value of convert()) to a coarser // resolution requires an explicit cast. const time_point tp_m = time_point_cast( convert(civil_second(2015, 1, 2, 3, 4, 5), utc)); EXPECT_EQ("04:00", format("%M:%E*S", tp_m, utc)); const time_point tp_h = time_point_cast( convert(civil_second(2015, 1, 2, 3, 4, 5), utc)); EXPECT_EQ("00:00", format("%M:%E*S", tp_h, utc)); } TEST(MakeTime, Normalization) { const time_zone tz = LoadZone("America/New_York"); const auto tp = convert(civil_second(2009, 2, 13, 18, 31, 30), tz); EXPECT_EQ(system_clock::from_time_t(1234567890), tp); // Now requests for the same time_point but with out-of-range fields. EXPECT_EQ(tp, convert(civil_second(2008, 14, 13, 18, 31, 30), tz)); // month EXPECT_EQ(tp, convert(civil_second(2009, 1, 44, 18, 31, 30), tz)); // day EXPECT_EQ(tp, convert(civil_second(2009, 2, 12, 42, 31, 30), tz)); // hour EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 17, 91, 30), tz)); // minute EXPECT_EQ(tp, convert(civil_second(2009, 2, 13, 18, 30, 90), tz)); // second } // NOTE: Run this with --copt=-ftrapv to detect overflow problems. TEST(MakeTime, SysSecondsLimits) { // Note: There are currently no time zones with extended transitions // that occur near time_point::max() or civil_second::max(), // so any civil-time conversion around those times will always be unique. const char RFC3339[] = "%Y-%m-%dT%H:%M:%S%Ez"; const time_zone utc = utc_time_zone(); const time_zone apia = LoadZone("Pacific/Apia"); const time_zone dawson = LoadZone("America/Dawson"); time_point tp; // Approach the maximal time_point value from below. tp = convert(civil_second(292277026596, 12, 4, 15, 30, 6), utc); EXPECT_EQ("292277026596-12-04T15:30:06+00:00", format(RFC3339, tp, utc)); tp = convert(civil_second(292277026596, 12, 4, 15, 30, 7), utc); EXPECT_EQ("292277026596-12-04T15:30:07+00:00", format(RFC3339, tp, utc)); EXPECT_EQ(time_point::max(), tp); tp = convert(civil_second(292277026596, 12, 4, 15, 30, 8), utc); EXPECT_EQ(time_point::max(), tp); tp = convert(civil_second::max(), utc); EXPECT_EQ(time_point::max(), tp); // Checks that we can also get the maximal value for a far-east zone. tp = convert(civil_second(292277026596, 12, 5, 5, 30, 7), apia); EXPECT_EQ("292277026596-12-05T05:30:07+14:00", format(RFC3339, tp, apia)); EXPECT_EQ(time_point::max(), tp); tp = convert(civil_second(292277026596, 12, 5, 5, 30, 8), apia); EXPECT_EQ(time_point::max(), tp); tp = convert(civil_second::max(), apia); EXPECT_EQ(time_point::max(), tp); // Checks that we can also get the maximal value for a far-west zone. tp = convert(civil_second(292277026596, 12, 4, 7, 30, 7), dawson); EXPECT_EQ("292277026596-12-04T07:30:07-08:00", format(RFC3339, tp, dawson)); EXPECT_EQ(time_point::max(), tp); tp = convert(civil_second(292277026596, 12, 4, 7, 30, 8), dawson); EXPECT_EQ(time_point::max(), tp); tp = convert(civil_second::max(), dawson); EXPECT_EQ(time_point::max(), tp); // Approach the minimal time_point value from above. tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 53), utc); EXPECT_EQ("-292277022657-01-27T08:29:53+00:00", format(RFC3339, tp, utc)); tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 52), utc); EXPECT_EQ("-292277022657-01-27T08:29:52+00:00", format(RFC3339, tp, utc)); EXPECT_EQ(time_point::min(), tp); tp = convert(civil_second(-292277022657, 1, 27, 8, 29, 51), utc); EXPECT_EQ(time_point::min(), tp); tp = convert(civil_second::min(), utc); EXPECT_EQ(time_point::min(), tp); // Checks that we can also get the minimal value for a far-east zone. tp = convert(civil_second(-292277022657, 1, 27, 21, 2, 56), apia); EXPECT_EQ("-292277022657-01-27T21:02:56+12:33", format(RFC3339, tp, apia)); EXPECT_EQ(time_point::min(), tp); tp = convert(civil_second(-292277022657, 1, 27, 21, 2, 55), apia); EXPECT_EQ(time_point::min(), tp); tp = convert(civil_second::min(), apia); EXPECT_EQ(time_point::min(), tp); // Checks that we can also get the minimal value for a far-west zone. tp = convert(civil_second(-292277022657, 1, 26, 23, 12, 12), dawson); EXPECT_EQ("-292277022657-01-26T23:12:12-09:17", format(RFC3339, tp, dawson)); EXPECT_EQ(time_point::min(), tp); tp = convert(civil_second(-292277022657, 1, 26, 23, 12, 11), dawson); EXPECT_EQ(time_point::min(), tp); tp = convert(civil_second::min(), dawson); EXPECT_EQ(time_point::min(), tp); } TEST(TimeZoneEdgeCase, AmericaNewYork) { const time_zone tz = LoadZone("America/New_York"); // Spring 1:59:59 -> 3:00:00 auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -5 * 3600, false, "EST"); tp += seconds(1); ExpectTime(tp, tz, 2013, 3, 10, 3, 0, 0, -4 * 3600, true, "EDT"); // Fall 1:59:59 -> 1:00:00 tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -4 * 3600, true, "EDT"); tp += seconds(1); ExpectTime(tp, tz, 2013, 11, 3, 1, 0, 0, -5 * 3600, false, "EST"); } TEST(TimeZoneEdgeCase, AmericaLosAngeles) { const time_zone tz = LoadZone("America/Los_Angeles"); // Spring 1:59:59 -> 3:00:00 auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -8 * 3600, false, "PST"); tp += seconds(1); ExpectTime(tp, tz, 2013, 3, 10, 3, 0, 0, -7 * 3600, true, "PDT"); // Fall 1:59:59 -> 1:00:00 tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -7 * 3600, true, "PDT"); tp += seconds(1); ExpectTime(tp, tz, 2013, 11, 3, 1, 0, 0, -8 * 3600, false, "PST"); } TEST(TimeZoneEdgeCase, ArizonaNoTransition) { const time_zone tz = LoadZone("America/Phoenix"); // No transition in Spring. auto tp = convert(civil_second(2013, 3, 10, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 3, 10, 1, 59, 59, -7 * 3600, false, "MST"); tp += seconds(1); ExpectTime(tp, tz, 2013, 3, 10, 2, 0, 0, -7 * 3600, false, "MST"); // No transition in Fall. tp = convert(civil_second(2013, 11, 3, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 11, 3, 1, 59, 59, -7 * 3600, false, "MST"); tp += seconds(1); ExpectTime(tp, tz, 2013, 11, 3, 2, 0, 0, -7 * 3600, false, "MST"); } TEST(TimeZoneEdgeCase, AsiaKathmandu) { const time_zone tz = LoadZone("Asia/Kathmandu"); // A non-DST offset change from +0530 to +0545 // // 504901799 == Tue, 31 Dec 1985 23:59:59 +0530 (+0530) // 504901800 == Wed, 1 Jan 1986 00:15:00 +0545 (+0545) auto tp = convert(civil_second(1985, 12, 31, 23, 59, 59), tz); ExpectTime(tp, tz, 1985, 12, 31, 23, 59, 59, 5.5 * 3600, false, "+0530"); tp += seconds(1); ExpectTime(tp, tz, 1986, 1, 1, 0, 15, 0, 5.75 * 3600, false, "+0545"); } TEST(TimeZoneEdgeCase, PacificChatham) { const time_zone tz = LoadZone("Pacific/Chatham"); // One-hour DST offset changes, but at atypical values // // 1365256799 == Sun, 7 Apr 2013 03:44:59 +1345 (+1345) // 1365256800 == Sun, 7 Apr 2013 02:45:00 +1245 (+1245) auto tp = convert(civil_second(2013, 4, 7, 3, 44, 59), tz); ExpectTime(tp, tz, 2013, 4, 7, 3, 44, 59, 13.75 * 3600, true, "+1345"); tp += seconds(1); ExpectTime(tp, tz, 2013, 4, 7, 2, 45, 0, 12.75 * 3600, false, "+1245"); // 1380376799 == Sun, 29 Sep 2013 02:44:59 +1245 (+1245) // 1380376800 == Sun, 29 Sep 2013 03:45:00 +1345 (+1345) tp = convert(civil_second(2013, 9, 29, 2, 44, 59), tz); ExpectTime(tp, tz, 2013, 9, 29, 2, 44, 59, 12.75 * 3600, false, "+1245"); tp += seconds(1); ExpectTime(tp, tz, 2013, 9, 29, 3, 45, 0, 13.75 * 3600, true, "+1345"); } TEST(TimeZoneEdgeCase, AustraliaLordHowe) { const time_zone tz = LoadZone("Australia/Lord_Howe"); // Half-hour DST offset changes // // 1365260399 == Sun, 7 Apr 2013 01:59:59 +1100 (+11) // 1365260400 == Sun, 7 Apr 2013 01:30:00 +1030 (+1030) auto tp = convert(civil_second(2013, 4, 7, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 4, 7, 1, 59, 59, 11 * 3600, true, "+11"); tp += seconds(1); ExpectTime(tp, tz, 2013, 4, 7, 1, 30, 0, 10.5 * 3600, false, "+1030"); // 1380986999 == Sun, 6 Oct 2013 01:59:59 +1030 (+1030) // 1380987000 == Sun, 6 Oct 2013 02:30:00 +1100 (+11) tp = convert(civil_second(2013, 10, 6, 1, 59, 59), tz); ExpectTime(tp, tz, 2013, 10, 6, 1, 59, 59, 10.5 * 3600, false, "+1030"); tp += seconds(1); ExpectTime(tp, tz, 2013, 10, 6, 2, 30, 0, 11 * 3600, true, "+11"); } TEST(TimeZoneEdgeCase, PacificApia) { const time_zone tz = LoadZone("Pacific/Apia"); // At the end of December 2011, Samoa jumped forward by one day, // skipping 30 December from the local calendar, when the nation // moved to the west of the International Date Line. // // A one-day, non-DST offset change // // 1325239199 == Thu, 29 Dec 2011 23:59:59 -1000 (-10) // 1325239200 == Sat, 31 Dec 2011 00:00:00 +1400 (+14) auto tp = convert(civil_second(2011, 12, 29, 23, 59, 59), tz); ExpectTime(tp, tz, 2011, 12, 29, 23, 59, 59, -10 * 3600, true, "-10"); EXPECT_EQ(363, get_yearday(civil_day(convert(tp, tz)))); tp += seconds(1); ExpectTime(tp, tz, 2011, 12, 31, 0, 0, 0, 14 * 3600, true, "+14"); EXPECT_EQ(365, get_yearday(civil_day(convert(tp, tz)))); } TEST(TimeZoneEdgeCase, AfricaCairo) { const time_zone tz = LoadZone("Africa/Cairo"); // An interesting case of midnight not existing. // // 1400191199 == Thu, 15 May 2014 23:59:59 +0200 (EET) // 1400191200 == Fri, 16 May 2014 01:00:00 +0300 (EEST) auto tp = convert(civil_second(2014, 5, 15, 23, 59, 59), tz); ExpectTime(tp, tz, 2014, 5, 15, 23, 59, 59, 2 * 3600, false, "EET"); tp += seconds(1); ExpectTime(tp, tz, 2014, 5, 16, 1, 0, 0, 3 * 3600, true, "EEST"); } TEST(TimeZoneEdgeCase, AfricaMonrovia) { const time_zone tz = LoadZone("Africa/Monrovia"); // Strange offset change -00:44:30 -> +00:00:00 (non-DST) // // 63593069 == Thu, 6 Jan 1972 23:59:59 -0044 (MMT) // 63593070 == Fri, 7 Jan 1972 00:44:30 +0000 (GMT) auto tp = convert(civil_second(1972, 1, 6, 23, 59, 59), tz); ExpectTime(tp, tz, 1972, 1, 6, 23, 59, 59, -44.5 * 60, false, "MMT"); tp += seconds(1); #ifndef TZDATA_2017B_IS_UBIQUITOUS // The 2017b tzdata release moved the shift from -004430 to +00 // from 1972-05-01 to 1972-01-07, so we temporarily accept both // outcomes until 2017b is ubiquitous. if (tz.lookup(tp).offset == -44.5 * 60) { tp = convert(civil_second(1972, 4, 30, 23, 59, 59), tz); ExpectTime(tp, tz, 1972, 4, 30, 23, 59, 59, -44.5 * 60, false, "LRT"); tp += seconds(1); ExpectTime(tp, tz, 1972, 5, 1, 0, 44, 30, 0 * 60, false, "GMT"); return; } #endif ExpectTime(tp, tz, 1972, 1, 7, 0, 44, 30, 0 * 60, false, "GMT"); } TEST(TimeZoneEdgeCase, AmericaJamaica) { // Jamaica discontinued DST transitions in 1983, and is now at a // constant -0500. This makes it an interesting edge-case target. // Note that the 32-bit times used in a (tzh_version == 0) zoneinfo // file cannot represent the abbreviation-only transition of 1890, // so we ignore the abbreviation by expecting what we received. const time_zone tz = LoadZone("America/Jamaica"); // Before the first transition. auto tp = convert(civil_second(1889, 12, 31, 0, 0, 0), tz); ExpectTime(tp, tz, 1889, 12, 31, 0, 0, 0, -18431, false, tz.lookup(tp).abbr); // Over the first (abbreviation-change only) transition. // -2524503170 == Tue, 31 Dec 1889 23:59:59 -0507 (LMT) // -2524503169 == Wed, 1 Jan 1890 00:00:00 -0507 (KMT) tp = convert(civil_second(1889, 12, 31, 23, 59, 59), tz); ExpectTime(tp, tz, 1889, 12, 31, 23, 59, 59, -18431, false, tz.lookup(tp).abbr); tp += seconds(1); ExpectTime(tp, tz, 1890, 1, 1, 0, 0, 0, -18431, false, "KMT"); // Over the last (DST) transition. // 436341599 == Sun, 30 Oct 1983 01:59:59 -0400 (EDT) // 436341600 == Sun, 30 Oct 1983 01:00:00 -0500 (EST) tp = convert(civil_second(1983, 10, 30, 1, 59, 59), tz); ExpectTime(tp, tz, 1983, 10, 30, 1, 59, 59, -4 * 3600, true, "EDT"); tp += seconds(1); ExpectTime(tp, tz, 1983, 10, 30, 1, 0, 0, -5 * 3600, false, "EST"); // After the last transition. tp = convert(civil_second(1983, 12, 31, 23, 59, 59), tz); ExpectTime(tp, tz, 1983, 12, 31, 23, 59, 59, -5 * 3600, false, "EST"); } TEST(TimeZoneEdgeCase, WET) { // Cover some non-existent times within forward transitions. const time_zone tz = LoadZone("WET"); // Before the first transition. auto tp = convert(civil_second(1977, 1, 1, 0, 0, 0), tz); ExpectTime(tp, tz, 1977, 1, 1, 0, 0, 0, 0, false, "WET"); // Over the first transition. // 228877199 == Sun, 3 Apr 1977 00:59:59 +0000 (WET) // 228877200 == Sun, 3 Apr 1977 02:00:00 +0100 (WEST) tp = convert(civil_second(1977, 4, 3, 0, 59, 59), tz); ExpectTime(tp, tz, 1977, 4, 3, 0, 59, 59, 0, false, "WET"); tp += seconds(1); ExpectTime(tp, tz, 1977, 4, 3, 2, 0, 0, 1 * 3600, true, "WEST"); // A non-existent time within the first transition. time_zone::civil_lookup cl1 = tz.lookup(civil_second(1977, 4, 3, 1, 15, 0)); EXPECT_EQ(time_zone::civil_lookup::SKIPPED, cl1.kind); ExpectTime(cl1.pre, tz, 1977, 4, 3, 2, 15, 0, 1 * 3600, true, "WEST"); ExpectTime(cl1.trans, tz, 1977, 4, 3, 2, 0, 0, 1 * 3600, true, "WEST"); ExpectTime(cl1.post, tz, 1977, 4, 3, 0, 15, 0, 0 * 3600, false, "WET"); // A non-existent time within the second forward transition. time_zone::civil_lookup cl2 = tz.lookup(civil_second(1978, 4, 2, 1, 15, 0)); EXPECT_EQ(time_zone::civil_lookup::SKIPPED, cl2.kind); ExpectTime(cl2.pre, tz, 1978, 4, 2, 2, 15, 0, 1 * 3600, true, "WEST"); ExpectTime(cl2.trans, tz, 1978, 4, 2, 2, 0, 0, 1 * 3600, true, "WEST"); ExpectTime(cl2.post, tz, 1978, 4, 2, 0, 15, 0, 0 * 3600, false, "WET"); } TEST(TimeZoneEdgeCase, FixedOffsets) { const time_zone gmtm5 = LoadZone("Etc/GMT+5"); // -0500 auto tp = convert(civil_second(1970, 1, 1, 0, 0, 0), gmtm5); ExpectTime(tp, gmtm5, 1970, 1, 1, 0, 0, 0, -5 * 3600, false, "-05"); EXPECT_EQ(system_clock::from_time_t(5 * 3600), tp); const time_zone gmtp5 = LoadZone("Etc/GMT-5"); // +0500 tp = convert(civil_second(1970, 1, 1, 0, 0, 0), gmtp5); ExpectTime(tp, gmtp5, 1970, 1, 1, 0, 0, 0, 5 * 3600, false, "+05"); EXPECT_EQ(system_clock::from_time_t(-5 * 3600), tp); } TEST(TimeZoneEdgeCase, NegativeYear) { // Tests transition from year 0 (aka 1BCE) to year -1. const time_zone tz = utc_time_zone(); auto tp = convert(civil_second(0, 1, 1, 0, 0, 0), tz); ExpectTime(tp, tz, 0, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC"); EXPECT_EQ(weekday::saturday, get_weekday(civil_day(convert(tp, tz)))); tp -= seconds(1); ExpectTime(tp, tz, -1, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC"); EXPECT_EQ(weekday::friday, get_weekday(civil_day(convert(tp, tz)))); } TEST(TimeZoneEdgeCase, UTC32bitLimit) { const time_zone tz = utc_time_zone(); // Limits of signed 32-bit time_t // // 2147483647 == Tue, 19 Jan 2038 03:14:07 +0000 (UTC) // 2147483648 == Tue, 19 Jan 2038 03:14:08 +0000 (UTC) auto tp = convert(civil_second(2038, 1, 19, 3, 14, 7), tz); ExpectTime(tp, tz, 2038, 1, 19, 3, 14, 7, 0 * 3600, false, "UTC"); tp += seconds(1); ExpectTime(tp, tz, 2038, 1, 19, 3, 14, 8, 0 * 3600, false, "UTC"); } TEST(TimeZoneEdgeCase, UTC5DigitYear) { const time_zone tz = utc_time_zone(); // Rollover to 5-digit year // // 253402300799 == Fri, 31 Dec 9999 23:59:59 +0000 (UTC) // 253402300800 == Sat, 1 Jan 1000 00:00:00 +0000 (UTC) auto tp = convert(civil_second(9999, 12, 31, 23, 59, 59), tz); ExpectTime(tp, tz, 9999, 12, 31, 23, 59, 59, 0 * 3600, false, "UTC"); tp += seconds(1); ExpectTime(tp, tz, 10000, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC"); } } // namespace cctz lubridate/src/cctz/src/time_zone_libc.cc0000644000176200001440000001051513263152652020046 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #if defined(_WIN32) || defined(_WIN64) #define _CRT_SECURE_NO_WARNINGS #endif #include "time_zone_libc.h" #include #include #include #include #include "civil_time.h" #include "time_zone.h" namespace cctz { namespace { // .first is seconds east of UTC; .second is the time-zone abbreviation. using OffsetAbbr = std::pair; // Defines a function that can be called as follows: // // std::tm tm = ...; // OffsetAbbr off_abbr = get_offset_abbr(tm); // #if defined(_WIN32) || defined(_WIN64) // Uses the globals: '_timezone', '_dstbias' and '_tzname'. OffsetAbbr get_offset_abbr(const std::tm& tm) { const bool is_dst = tm.tm_isdst > 0; const int off = _timezone + (is_dst ? _dstbias : 0); const char* abbr = _tzname[is_dst]; return {off, abbr}; } #elif defined(__sun) // Uses the globals: 'timezone', 'altzone' and 'tzname'. OffsetAbbr get_offset_abbr(const std::tm& tm) { const bool is_dst = tm.tm_isdst > 0; const int off = is_dst ? altzone : timezone; const char* abbr = tzname[is_dst]; return {off, abbr}; } #elif defined(__native_client__) || defined(__myriad2__) || defined(__asmjs__) // Uses the globals: 'timezone' and 'tzname'. OffsetAbbr get_offset_abbr(const std::tm& tm) { const bool is_dst = tm.tm_isdst > 0; const int off = _timezone + (is_dst ? 60 * 60 : 0); const char* abbr = tzname[is_dst]; return {off, abbr}; } #else // // Returns an OffsetAbbr using std::tm fields with various spellings. // #if !defined(tm_gmtoff) && !defined(tm_zone) template OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::tm_gmtoff) = nullptr, decltype(&T::tm_zone) = nullptr) { return {tm.tm_gmtoff, tm.tm_zone}; } #endif // !defined(tm_gmtoff) && !defined(tm_zone) #if !defined(__tm_gmtoff) && !defined(__tm_zone) template OffsetAbbr get_offset_abbr(const T& tm, decltype(&T::__tm_gmtoff) = nullptr, decltype(&T::__tm_zone) = nullptr) { return {tm.__tm_gmtoff, tm.__tm_zone}; } #endif // !defined(__tm_gmtoff) && !defined(__tm_zone) #endif } // namespace TimeZoneLibC::TimeZoneLibC(const std::string& name) : local_(name == "localtime") {} time_zone::absolute_lookup TimeZoneLibC::BreakTime( const time_point& tp) const { time_zone::absolute_lookup al; std::time_t t = ToUnixSeconds(tp); std::tm tm; if (local_) { #if defined(_WIN32) || defined(_WIN64) localtime_s(&tm, &t); #else localtime_r(&t, &tm); #endif std::tie(al.offset, al.abbr) = get_offset_abbr(tm); } else { #if defined(_WIN32) || defined(_WIN64) gmtime_s(&tm, &t); #else gmtime_r(&t, &tm); #endif al.offset = 0; al.abbr = "UTC"; } al.cs = civil_second(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); al.is_dst = tm.tm_isdst > 0; return al; } time_zone::civil_lookup TimeZoneLibC::MakeTime(const civil_second& cs) const { time_zone::civil_lookup cl; std::time_t t; if (local_) { // Does not handle SKIPPED/AMBIGUOUS or huge years. std::tm tm; tm.tm_year = static_cast(cs.year() - 1900); tm.tm_mon = cs.month() - 1; tm.tm_mday = cs.day(); tm.tm_hour = cs.hour(); tm.tm_min = cs.minute(); tm.tm_sec = cs.second(); tm.tm_isdst = -1; t = std::mktime(&tm); } else { t = cs - civil_second(); } cl.kind = time_zone::civil_lookup::UNIQUE; cl.pre = cl.trans = cl.post = FromUnixSeconds(t); return cl; } std::string TimeZoneLibC::Description() const { return local_ ? "localtime" : "UTC"; } bool TimeZoneLibC::NextTransition(time_point* tp) const { return false; } bool TimeZoneLibC::PrevTransition(time_point* tp) const { return false; } } // namespace cctz lubridate/src/cctz/src/time_zone_posix.h0000644000176200001440000000717113263152652020145 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // Parsing of a POSIX zone spec as described in the TZ part of section 8.3 in // http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html. // // The current POSIX spec for America/Los_Angeles is "PST8PDT,M3.2.0,M11.1.0", // which would be broken down as ... // // PosixTimeZone { // std_abbr = "PST" // std_offset = -28800 // dst_abbr = "PDT" // dst_offset = -25200 // dst_start = PosixTransition { // date { // m { // month = 3 // week = 2 // weekday = 0 // } // } // time { // offset = 7200 // } // } // dst_end = PosixTransition { // date { // m { // month = 11 // week = 1 // weekday = 0 // } // } // time { // offset = 7200 // } // } // } #ifndef CCTZ_TIME_ZONE_POSIX_H_ #define CCTZ_TIME_ZONE_POSIX_H_ #include #include namespace cctz { // The date/time of the transition. The date is specified as either: // (J) the Nth day of the year (1 <= N <= 365), excluding leap days, or // (N) the Nth day of the year (0 <= N <= 365), including leap days, or // (M) the Nth weekday of a month (e.g., the 2nd Sunday in March). // The time, specified as a day offset, identifies the particular moment // of the transition, and may be negative or >= 24h, and in which case // it would take us to another day, and perhaps week, or even month. struct PosixTransition { enum DateFormat { J, N, M }; struct { DateFormat fmt; union { struct { std::int_fast16_t day; // day of non-leap year [1:365] } j; struct { std::int_fast16_t day; // day of year [0:365] } n; struct { std::int_fast8_t month; // month of year [1:12] std::int_fast8_t week; // week of month [1:5] (5==last) std::int_fast8_t weekday; // 0==Sun, ..., 6=Sat } m; }; } date; struct { std::int_fast32_t offset; // seconds before/after 00:00:00 } time; }; // The entirety of a POSIX-string specified time-zone rule. The standard // abbreviation and offset are always given. If the time zone includes // daylight saving, then the daylight abbrevation is non-empty and the // remaining fields are also valid. Note that the start/end transitions // are not ordered---in the southern hemisphere the transition to end // daylight time occurs first in any particular year. struct PosixTimeZone { std::string std_abbr; std::int_fast32_t std_offset; std::string dst_abbr; std::int_fast32_t dst_offset; PosixTransition dst_start; PosixTransition dst_end; }; // Breaks down a POSIX time-zone specification into its constituent pieces, // filling in any missing values (DST offset, or start/end transition times) // with the standard-defined defaults. Returns false if the specification // could not be parsed (although some fields of *res may have been altered). bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res); } // namespace cctz #endif // CCTZ_TIME_ZONE_POSIX_H_ lubridate/src/cctz/src/time_zone_info.h0000644000176200001440000001156613263152652017741 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CCTZ_TIME_ZONE_INFO_H_ #define CCTZ_TIME_ZONE_INFO_H_ #include #include #include #include #include #include "civil_time.h" #include "time_zone.h" #include "time_zone_if.h" #include "tzfile.h" #include "zone_info_source.h" namespace cctz { // A transition to a new UTC offset. struct Transition { std::int_least64_t unix_time; // the instant of this transition std::uint_least8_t type_index; // index of the transition type civil_second civil_sec; // local civil time of transition civil_second prev_civil_sec; // local civil time one second earlier struct ByUnixTime { inline bool operator()(const Transition& lhs, const Transition& rhs) const { return lhs.unix_time < rhs.unix_time; } }; struct ByCivilTime { inline bool operator()(const Transition& lhs, const Transition& rhs) const { return lhs.civil_sec < rhs.civil_sec; } }; }; // The characteristics of a particular transition. struct TransitionType { std::int_least32_t utc_offset; // the new prevailing UTC offset civil_second civil_max; // max convertible civil time for offset civil_second civil_min; // min convertible civil time for offset bool is_dst; // did we move into daylight-saving time std::uint_least8_t abbr_index; // index of the new abbreviation }; // A time zone backed by the IANA Time Zone Database (zoneinfo). class TimeZoneInfo : public TimeZoneIf { public: TimeZoneInfo() = default; TimeZoneInfo(const TimeZoneInfo&) = delete; TimeZoneInfo& operator=(const TimeZoneInfo&) = delete; // Loads the zoneinfo for the given name, returning true if successful. bool Load(const std::string& name); // TimeZoneIf implementations. time_zone::absolute_lookup BreakTime( const time_point& tp) const override; time_zone::civil_lookup MakeTime( const civil_second& cs) const override; std::string Description() const override; bool NextTransition(time_point* tp) const override; bool PrevTransition(time_point* tp) const override; private: struct Header { // counts of: std::size_t timecnt; // transition times std::size_t typecnt; // transition types std::size_t charcnt; // zone abbreviation characters std::size_t leapcnt; // leap seconds (we expect none) std::size_t ttisstdcnt; // UTC/local indicators (unused) std::size_t ttisgmtcnt; // standard/wall indicators (unused) bool Build(const tzhead& tzh); std::size_t DataLength(std::size_t time_len) const; }; void CheckTransition(const std::string& name, const TransitionType& tt, std::int_fast32_t offset, bool is_dst, const std::string& abbr) const; bool EquivTransitions(std::uint_fast8_t tt1_index, std::uint_fast8_t tt2_index) const; void ExtendTransitions(const std::string& name, const Header& hdr); bool ResetToBuiltinUTC(const sys_seconds& offset); bool Load(const std::string& name, ZoneInfoSource* zip); // Helpers for BreakTime() and MakeTime() respectively. time_zone::absolute_lookup LocalTime(std::int_fast64_t unix_time, const TransitionType& tt) const; time_zone::civil_lookup TimeLocal(const civil_second& cs, cctz::year_t c4_shift) const; std::vector transitions_; // ordered by unix_time and civil_sec std::vector transition_types_; // distinct transition types std::uint_fast8_t default_transition_type_; // for before first transition std::string abbreviations_; // all the NUL-terminated abbreviations std::string future_spec_; // for after the last zic transition bool extended_; // future_spec_ was used to generate transitions cctz::year_t last_year_; // the final year of the generated transitions // We remember the transitions found during the last BreakTime() and // MakeTime() calls. If the next request is for the same transition we // will avoid re-searching. mutable std::atomic local_time_hint_ = {}; // BreakTime() hint mutable std::atomic time_local_hint_ = {}; // MakeTime() hint }; } // namespace cctz #endif // CCTZ_TIME_ZONE_INFO_H_ lubridate/src/cctz/src/time_zone_impl.cc0000644000176200001440000000620613263152652020100 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "time_zone_impl.h" #include #include #include #include #include "time_zone_fixed.h" namespace cctz { namespace { // time_zone::Impls are linked into a map to support fast lookup by name. using TimeZoneImplByName = std::unordered_map; TimeZoneImplByName* time_zone_map = nullptr; // Mutual exclusion for time_zone_map. std::mutex time_zone_mutex; } // namespace time_zone time_zone::Impl::UTC() { return time_zone(UTCImpl()); } bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) { const time_zone::Impl* const utc_impl = UTCImpl(); // First check for UTC (which is never a key in time_zone_map). auto offset = sys_seconds::zero(); if (FixedOffsetFromName(name, &offset) && offset == sys_seconds::zero()) { *tz = time_zone(utc_impl); return true; } // Then check, under a shared lock, whether the time zone has already // been loaded. This is the common path. TODO: Move to shared_mutex. { std::lock_guard lock(time_zone_mutex); if (time_zone_map != nullptr) { TimeZoneImplByName::const_iterator itr = time_zone_map->find(name); if (itr != time_zone_map->end()) { *tz = time_zone(itr->second); return itr->second != utc_impl; } } } // Now check again, under an exclusive lock. std::lock_guard lock(time_zone_mutex); if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName; const Impl*& impl = (*time_zone_map)[name]; if (impl == nullptr) { // The first thread in loads the new time zone. Impl* new_impl = new Impl(name); new_impl->zone_ = TimeZoneIf::Load(new_impl->name_); if (new_impl->zone_ == nullptr) { delete new_impl; // free the nascent Impl impl = utc_impl; // and fallback to UTC } else { impl = new_impl; // install new time zone } } *tz = time_zone(impl); return impl != utc_impl; } const time_zone::Impl& time_zone::Impl::get(const time_zone& tz) { if (tz.impl_ == nullptr) { // Dereferencing an implicit-UTC time_zone is expected to be // rare, so we don't mind paying a small synchronization cost. return *UTCImpl(); } return *tz.impl_; } time_zone::Impl::Impl(const std::string& name) : name_(name) {} const time_zone::Impl* time_zone::Impl::UTCImpl() { static Impl* utc_impl = [] { Impl* impl = new Impl("UTC"); impl->zone_ = TimeZoneIf::Load(impl->name_); // never fails return impl; }(); return utc_impl; } } // namespace cctz lubridate/src/cctz/src/time_zone_impl.h0000644000176200001440000000631213263152652017740 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CCTZ_TIME_ZONE_IMPL_H_ #define CCTZ_TIME_ZONE_IMPL_H_ #include #include #include "civil_time.h" #include "time_zone.h" #include "time_zone_if.h" #include "time_zone_info.h" namespace cctz { // time_zone::Impl is the internal object referenced by a cctz::time_zone. class time_zone::Impl { public: // The UTC time zone. Also used for other time zones that fail to load. static time_zone UTC(); // Load a named time zone. Returns false if the name is invalid, or if // some other kind of error occurs. Note that loading "UTC" never fails. static bool LoadTimeZone(const std::string& name, time_zone* tz); // Dereferences the time_zone to obtain its Impl. static const time_zone::Impl& get(const time_zone& tz); // The primary key is the time-zone ID (e.g., "America/New_York"). const std::string& name() const { return name_; } // Breaks a time_point down to civil-time components in this time zone. time_zone::absolute_lookup BreakTime( const time_point& tp) const { return zone_->BreakTime(tp); } // Converts the civil-time components in this time zone into a time_point. // That is, the opposite of BreakTime(). The requested civil time may be // ambiguous or illegal due to a change of UTC offset. time_zone::civil_lookup MakeTime(const civil_second& cs) const { return zone_->MakeTime(cs); } // Returns an implementation-specific description of this time zone. std::string Description() const { return zone_->Description(); } // Finds the time of the next/previous offset change in this time zone. // // By definition, NextTransition(&tp) returns false when tp has its // maximum value, and PrevTransition(&tp) returns false when tp has its // mimimum value. If the zone has no transitions, the result will also // be false no matter what the argument. // // Otherwise, when tp has its mimimum value, NextTransition(&tp) returns // true and sets tp to the first recorded transition. Chains of calls // to NextTransition()/PrevTransition() will eventually return false, // but it is unspecified exactly when NextTransition(&tp) jumps to false, // or what time is set by PrevTransition(&tp) for a very distant tp. bool NextTransition(time_point* tp) const { return zone_->NextTransition(tp); } bool PrevTransition(time_point* tp) const { return zone_->PrevTransition(tp); } private: explicit Impl(const std::string& name); static const Impl* UTCImpl(); const std::string name_; std::unique_ptr zone_; }; } // namespace cctz #endif // CCTZ_TIME_ZONE_IMPL_H_ lubridate/src/cctz/src/time_zone_libc.h0000644000176200001440000000277513263152652017721 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CCTZ_TIME_ZONE_LIBC_H_ #define CCTZ_TIME_ZONE_LIBC_H_ #include #include "time_zone_if.h" namespace cctz { // A time zone backed by gmtime_r(3), localtime_r(3), and mktime(3), // and which therefore only supports UTC and the local time zone. // TODO: Add support for fixed offsets from UTC. class TimeZoneLibC : public TimeZoneIf { public: explicit TimeZoneLibC(const std::string& name); // TimeZoneIf implementations. time_zone::absolute_lookup BreakTime( const time_point& tp) const override; time_zone::civil_lookup MakeTime( const civil_second& cs) const override; std::string Description() const override; bool NextTransition(time_point* tp) const override; bool PrevTransition(time_point* tp) const override; private: const bool local_; // localtime or UTC }; } // namespace cctz #endif // CCTZ_TIME_ZONE_LIBC_H_ lubridate/src/cctz/src/time_zone_lookup.cc0000644000176200001440000000507413263152652020452 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "time_zone.h" #include #include #include #include "time_zone_fixed.h" #include "time_zone_impl.h" namespace cctz { std::string time_zone::name() const { return time_zone::Impl::get(*this).name(); } time_zone::absolute_lookup time_zone::lookup( const time_point& tp) const { return time_zone::Impl::get(*this).BreakTime(tp); } time_zone::civil_lookup time_zone::lookup(const civil_second& cs) const { return time_zone::Impl::get(*this).MakeTime(cs); } bool operator==(time_zone lhs, time_zone rhs) { return &time_zone::Impl::get(lhs) == &time_zone::Impl::get(rhs); } bool load_time_zone(const std::string& name, time_zone* tz) { return time_zone::Impl::LoadTimeZone(name, tz); } time_zone utc_time_zone() { return time_zone::Impl::UTC(); // avoid name lookup } time_zone fixed_time_zone(const sys_seconds& offset) { time_zone tz; load_time_zone(FixedOffsetToName(offset), &tz); return tz; } time_zone local_time_zone() { const char* zone = ":localtime"; // Allow ${TZ} to override to default zone. char* tz_env = nullptr; #if defined(_MSC_VER) _dupenv_s(&tz_env, nullptr, "TZ"); #else tz_env = std::getenv("TZ"); #endif if (tz_env) zone = tz_env; // We only support the "[:]" form. if (*zone == ':') ++zone; // Map "localtime" to a system-specific name, but // allow ${LOCALTIME} to override the default name. char* localtime_env = nullptr; if (strcmp(zone, "localtime") == 0) { #if defined(_MSC_VER) // System-specific default is just "localtime". _dupenv_s(&localtime_env, nullptr, "LOCALTIME"); #else zone = "/etc/localtime"; // System-specific default. localtime_env = std::getenv("LOCALTIME"); #endif if (localtime_env) zone = localtime_env; } const std::string name = zone; #if defined(_MSC_VER) free(localtime_env); free(tz_env); #endif time_zone tz; load_time_zone(name, &tz); // Falls back to UTC. return tz; } } // namespace cctz lubridate/src/cctz/include/0000755000176200001440000000000013201152061015371 5ustar liggesuserslubridate/src/cctz/include/civil_time_detail.h0000644000176200001440000004420013263152652021226 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CCTZ_CIVIL_TIME_DETAIL_H_ #define CCTZ_CIVIL_TIME_DETAIL_H_ #include #include #include #include // Disable constexpr support unless we are using clang in C++14 mode. #if __clang__ && __cpp_constexpr >= 201304 #define CONSTEXPR_D constexpr // data #define CONSTEXPR_F constexpr // function #define CONSTEXPR_M constexpr // member #else #define CONSTEXPR_D const #define CONSTEXPR_F inline #define CONSTEXPR_M #endif namespace cctz { // Support years that at least span the range of 64-bit time_t values. using year_t = std::int_fast64_t; // Type alias that indicates an argument is not normalized (e.g., the // constructor parameters and operands/results of addition/subtraction). using diff_t = std::int_fast64_t; namespace detail { // Type aliases that indicate normalized argument values. using month_t = std::int_fast8_t; // [1:12] using day_t = std::int_fast8_t; // [1:31] using hour_t = std::int_fast8_t; // [0:23] using minute_t = std::int_fast8_t; // [0:59] using second_t = std::int_fast8_t; // [0:59] // Normalized civil-time fields: Y-M-D HH:MM:SS. struct fields { CONSTEXPR_M fields(year_t year, month_t month, day_t day, hour_t hour, minute_t minute, second_t second) : y(year), m(month), d(day), hh(hour), mm(minute), ss(second) {} std::int_least64_t y; std::int_least8_t m; std::int_least8_t d; std::int_least8_t hh; std::int_least8_t mm; std::int_least8_t ss; }; struct second_tag {}; struct minute_tag : second_tag {}; struct hour_tag : minute_tag {}; struct day_tag : hour_tag {}; struct month_tag : day_tag {}; struct year_tag : month_tag {}; //////////////////////////////////////////////////////////////////////// // Field normalization (without avoidable overflow). namespace impl { CONSTEXPR_F bool is_leap_year(year_t y) noexcept { return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0); } CONSTEXPR_F int year_index(year_t y, month_t m) noexcept { return (static_cast((y + (m > 2)) % 400) + 400) % 400; } CONSTEXPR_F int days_per_century(year_t y, month_t m) noexcept { const int yi = year_index(y, m); return 36524 + (yi == 0 || yi > 300); } CONSTEXPR_F int days_per_4years(year_t y, month_t m) noexcept { const int yi = year_index(y, m); return 1460 + (yi == 0 || yi > 300 || (yi - 1) % 100 < 96); } CONSTEXPR_F int days_per_year(year_t y, month_t m) noexcept { return is_leap_year(y + (m > 2)) ? 366 : 365; } CONSTEXPR_F int days_per_month(year_t y, month_t m) noexcept { CONSTEXPR_D signed char k_days_per_month[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 // non leap year }; return k_days_per_month[m - 1] + (m == 2 && is_leap_year(y)); } CONSTEXPR_F fields n_day(year_t y, month_t m, diff_t d, diff_t cd, hour_t hh, minute_t mm, second_t ss) noexcept { y += (cd / 146097) * 400; cd %= 146097; if (cd < 0) { y -= 400; cd += 146097; } y += (d / 146097) * 400; d = d % 146097 + cd; if (d <= 0) { y -= 400; d += 146097; } else if (d > 146097) { y += 400; d -= 146097; } if (d > 365) { for (int n = days_per_century(y, m); d > n; n = days_per_century(y, m)) { d -= n; y += 100; } for (int n = days_per_4years(y, m); d > n; n = days_per_4years(y, m)) { d -= n; y += 4; } for (int n = days_per_year(y, m); d > n; n = days_per_year(y, m)) { d -= n; ++y; } } if (d > 28) { for (int n = days_per_month(y, m); d > n; n = days_per_month(y, m)) { d -= n; if (++m > 12) { ++y; m = 1; } } } return fields(y, m, static_cast(d), hh, mm, ss); } CONSTEXPR_F fields n_mon(year_t y, diff_t m, diff_t d, diff_t cd, hour_t hh, minute_t mm, second_t ss) noexcept { if (m != 12) { y += m / 12; m %= 12; if (m <= 0) { y -= 1; m += 12; } } return n_day(y, static_cast(m), d, cd, hh, mm, ss); } CONSTEXPR_F fields n_hour(year_t y, diff_t m, diff_t d, diff_t cd, diff_t hh, minute_t mm, second_t ss) noexcept { cd += hh / 24; hh %= 24; if (hh < 0) { cd -= 1; hh += 24; } return n_mon(y, m, d, cd, static_cast(hh), mm, ss); } CONSTEXPR_F fields n_min(year_t y, diff_t m, diff_t d, diff_t hh, diff_t ch, diff_t mm, second_t ss) noexcept { ch += mm / 60; mm %= 60; if (mm < 0) { ch -= 1; mm += 60; } return n_hour(y, m, d, hh / 24 + ch / 24, hh % 24 + ch % 24, static_cast(mm), ss); } CONSTEXPR_F fields n_sec(year_t y, diff_t m, diff_t d, diff_t hh, diff_t mm, diff_t ss) noexcept { // Optimization for when (non-constexpr) fields are already normalized. if (0 <= ss && ss < 60) { const second_t nss = static_cast(ss); if (0 <= mm && mm < 60) { const minute_t nmm = static_cast(mm); if (0 <= hh && hh < 24) { const hour_t nhh = static_cast(hh); if (1 <= d && d <= 28 && 1 <= m && m <= 12) { const day_t nd = static_cast(d); const month_t nm = static_cast(m); return fields(y, nm, nd, nhh, nmm, nss); } return n_mon(y, m, d, 0, nhh, nmm, nss); } return n_hour(y, m, d, hh / 24, hh % 24, nmm, nss); } return n_min(y, m, d, hh, mm / 60, mm % 60, nss); } diff_t cm = ss / 60; ss %= 60; if (ss < 0) { cm -= 1; ss += 60; } return n_min(y, m, d, hh, mm / 60 + cm / 60, mm % 60 + cm % 60, static_cast(ss)); } } // namespace impl //////////////////////////////////////////////////////////////////////// // Increments the indicated (normalized) field by "n". CONSTEXPR_F fields step(second_tag, fields f, diff_t n) noexcept { return impl::n_sec(f.y, f.m, f.d, f.hh, f.mm + n / 60, f.ss + n % 60); } CONSTEXPR_F fields step(minute_tag, fields f, diff_t n) noexcept { return impl::n_min(f.y, f.m, f.d, f.hh + n / 60, 0, f.mm + n % 60, f.ss); } CONSTEXPR_F fields step(hour_tag, fields f, diff_t n) noexcept { return impl::n_hour(f.y, f.m, f.d + n / 24, 0, f.hh + n % 24, f.mm, f.ss); } CONSTEXPR_F fields step(day_tag, fields f, diff_t n) noexcept { return impl::n_day(f.y, f.m, f.d, n, f.hh, f.mm, f.ss); } CONSTEXPR_F fields step(month_tag, fields f, diff_t n) noexcept { return impl::n_mon(f.y + n / 12, f.m + n % 12, f.d, 0, f.hh, f.mm, f.ss); } CONSTEXPR_F fields step(year_tag, fields f, diff_t n) noexcept { return fields(f.y + n, f.m, f.d, f.hh, f.mm, f.ss); } //////////////////////////////////////////////////////////////////////// namespace impl { // Returns (v * f + a) but avoiding intermediate overflow when possible. CONSTEXPR_F diff_t scale_add(diff_t v, diff_t f, diff_t a) noexcept { return (v < 0) ? ((v + 1) * f + a) - f : ((v - 1) * f + a) + f; } // Map a (normalized) Y/M/D to the number of days before/after 1970-01-01. // Probably overflows for years outside [-292277022656:292277026595]. CONSTEXPR_F diff_t ymd_ord(year_t y, month_t m, day_t d) noexcept { const diff_t eyear = (m <= 2) ? y - 1 : y; const diff_t era = (eyear >= 0 ? eyear : eyear - 399) / 400; const diff_t yoe = eyear - era * 400; const diff_t doy = (153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; const diff_t doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; return era * 146097 + doe - 719468; } // Returns the difference in days between two normalized Y-M-D tuples. // ymd_ord() will encounter integer overflow given extreme year values, // yet the difference between two such extreme values may actually be // small, so we take a little care to avoid overflow when possible by // exploiting the 146097-day cycle. CONSTEXPR_F diff_t day_difference(year_t y1, month_t m1, day_t d1, year_t y2, month_t m2, day_t d2) noexcept { const diff_t a_c4_off = y1 % 400; const diff_t b_c4_off = y2 % 400; diff_t c4_diff = (y1 - a_c4_off) - (y2 - b_c4_off); diff_t delta = ymd_ord(a_c4_off, m1, d1) - ymd_ord(b_c4_off, m2, d2); if (c4_diff > 0 && delta < 0) { delta += 2 * 146097; c4_diff -= 2 * 400; } else if (c4_diff < 0 && delta > 0) { delta -= 2 * 146097; c4_diff += 2 * 400; } return (c4_diff / 400 * 146097) + delta; } } // namespace impl // Returns the difference between fields structs using the indicated unit. CONSTEXPR_F diff_t difference(year_tag, fields f1, fields f2) noexcept { return f1.y - f2.y; } CONSTEXPR_F diff_t difference(month_tag, fields f1, fields f2) noexcept { return impl::scale_add(difference(year_tag{}, f1, f2), 12, (f1.m - f2.m)); } CONSTEXPR_F diff_t difference(day_tag, fields f1, fields f2) noexcept { return impl::day_difference(f1.y, f1.m, f1.d, f2.y, f2.m, f2.d); } CONSTEXPR_F diff_t difference(hour_tag, fields f1, fields f2) noexcept { return impl::scale_add(difference(day_tag{}, f1, f2), 24, (f1.hh - f2.hh)); } CONSTEXPR_F diff_t difference(minute_tag, fields f1, fields f2) noexcept { return impl::scale_add(difference(hour_tag{}, f1, f2), 60, (f1.mm - f2.mm)); } CONSTEXPR_F diff_t difference(second_tag, fields f1, fields f2) noexcept { return impl::scale_add(difference(minute_tag{}, f1, f2), 60, f1.ss - f2.ss); } //////////////////////////////////////////////////////////////////////// // Aligns the (normalized) fields struct to the indicated field. CONSTEXPR_F fields align(second_tag, fields f) noexcept { return f; } CONSTEXPR_F fields align(minute_tag, fields f) noexcept { return fields{f.y, f.m, f.d, f.hh, f.mm, 0}; } CONSTEXPR_F fields align(hour_tag, fields f) noexcept { return fields{f.y, f.m, f.d, f.hh, 0, 0}; } CONSTEXPR_F fields align(day_tag, fields f) noexcept { return fields{f.y, f.m, f.d, 0, 0, 0}; } CONSTEXPR_F fields align(month_tag, fields f) noexcept { return fields{f.y, f.m, 1, 0, 0, 0}; } CONSTEXPR_F fields align(year_tag, fields f) noexcept { return fields{f.y, 1, 1, 0, 0, 0}; } //////////////////////////////////////////////////////////////////////// template class civil_time { public: explicit CONSTEXPR_M civil_time(year_t y, diff_t m = 1, diff_t d = 1, diff_t hh = 0, diff_t mm = 0, diff_t ss = 0) noexcept : civil_time(impl::n_sec(y, m, d, hh, mm, ss)) {} CONSTEXPR_M civil_time() noexcept : f_{1970, 1, 1, 0, 0, 0} {} civil_time(const civil_time&) = default; civil_time& operator=(const civil_time&) = default; // Conversion between civil times of different alignment. Conversion to // a more precise alignment is allowed implicitly (e.g., day -> hour), // but conversion where information is discarded must be explicit // (e.g., second -> minute). template using preserves_data = typename std::enable_if::value>::type; template CONSTEXPR_M civil_time(const civil_time& ct, preserves_data* = nullptr) noexcept : civil_time(ct.f_) {} template explicit CONSTEXPR_M civil_time(const civil_time& ct, preserves_data* = nullptr) noexcept : civil_time(ct.f_) {} // Factories for the maximum/minimum representable civil_time. static civil_time max() { const auto max_year = std::numeric_limits::max(); return civil_time(max_year, 12, 31, 23, 59, 59); } static civil_time min() { const auto min_year = std::numeric_limits::min(); return civil_time(min_year, 1, 1, 0, 0, 0); } // Field accessors. Note: All but year() return an int. CONSTEXPR_M year_t year() const noexcept { return f_.y; } CONSTEXPR_M int month() const noexcept { return f_.m; } CONSTEXPR_M int day() const noexcept { return f_.d; } CONSTEXPR_M int hour() const noexcept { return f_.hh; } CONSTEXPR_M int minute() const noexcept { return f_.mm; } CONSTEXPR_M int second() const noexcept { return f_.ss; } // Assigning arithmetic. CONSTEXPR_M civil_time& operator+=(diff_t n) noexcept { f_ = step(T{}, f_, n); return *this; } CONSTEXPR_M civil_time& operator-=(diff_t n) noexcept { if (n != std::numeric_limits::min()) { f_ = step(T{}, f_, -n); } else { f_ = step(T{}, step(T{}, f_, -(n + 1)), 1); } return *this; } CONSTEXPR_M civil_time& operator++() noexcept { return *this += 1; } CONSTEXPR_M civil_time operator++(int) noexcept { const civil_time a = *this; ++*this; return a; } CONSTEXPR_M civil_time& operator--() noexcept { return *this -= 1; } CONSTEXPR_M civil_time operator--(int) noexcept { const civil_time a = *this; --*this; return a; } // Binary arithmetic operators. inline friend CONSTEXPR_M civil_time operator+(civil_time a, diff_t n) noexcept { return a += n; } inline friend CONSTEXPR_M civil_time operator+(diff_t n, civil_time a) noexcept { return a += n; } inline friend CONSTEXPR_M civil_time operator-(civil_time a, diff_t n) noexcept { return a -= n; } inline friend CONSTEXPR_M diff_t operator-(const civil_time& lhs, const civil_time& rhs) noexcept { return difference(T{}, lhs.f_, rhs.f_); } private: // All instantiations of this template are allowed to call the following // private constructor and access the private fields member. template friend class civil_time; // The designated constructor that all others eventually call. explicit CONSTEXPR_M civil_time(fields f) noexcept : f_(align(T{}, f)) {} fields f_; }; // Disallows difference between differently aligned types. // auto n = civil_day(...) - civil_hour(...); // would be confusing. template CONSTEXPR_F diff_t operator-(civil_time, civil_time) = delete; using civil_year = civil_time; using civil_month = civil_time; using civil_day = civil_time; using civil_hour = civil_time; using civil_minute = civil_time; using civil_second = civil_time; //////////////////////////////////////////////////////////////////////// // Relational operators that work with differently aligned objects. // Always compares all six fields. template CONSTEXPR_F bool operator<(const civil_time& lhs, const civil_time& rhs) noexcept { return (lhs.year() < rhs.year() || (lhs.year() == rhs.year() && (lhs.month() < rhs.month() || (lhs.month() == rhs.month() && (lhs.day() < rhs.day() || (lhs.day() == rhs.day() && (lhs.hour() < rhs.hour() || (lhs.hour() == rhs.hour() && (lhs.minute() < rhs.minute() || (lhs.minute() == rhs.minute() && (lhs.second() < rhs.second()))))))))))); } template CONSTEXPR_F bool operator<=(const civil_time& lhs, const civil_time& rhs) noexcept { return !(rhs < lhs); } template CONSTEXPR_F bool operator>=(const civil_time& lhs, const civil_time& rhs) noexcept { return !(lhs < rhs); } template CONSTEXPR_F bool operator>(const civil_time& lhs, const civil_time& rhs) noexcept { return rhs < lhs; } template CONSTEXPR_F bool operator==(const civil_time& lhs, const civil_time& rhs) noexcept { return lhs.year() == rhs.year() && lhs.month() == rhs.month() && lhs.day() == rhs.day() && lhs.hour() == rhs.hour() && lhs.minute() == rhs.minute() && lhs.second() == rhs.second(); } template CONSTEXPR_F bool operator!=(const civil_time& lhs, const civil_time& rhs) noexcept { return !(lhs == rhs); } //////////////////////////////////////////////////////////////////////// enum class weekday { monday, tuesday, wednesday, thursday, friday, saturday, sunday, }; CONSTEXPR_F weekday get_weekday(const civil_day& cd) noexcept { CONSTEXPR_D weekday k_weekday_by_thu_off[] = { weekday::thursday, weekday::friday, weekday::saturday, weekday::sunday, weekday::monday, weekday::tuesday, weekday::wednesday, }; return k_weekday_by_thu_off[((cd - civil_day()) % 7 + 7) % 7]; } //////////////////////////////////////////////////////////////////////// CONSTEXPR_F civil_day next_weekday(civil_day cd, weekday wd) noexcept { do { cd += 1; } while (get_weekday(cd) != wd); return cd; } CONSTEXPR_F civil_day prev_weekday(civil_day cd, weekday wd) noexcept { do { cd -= 1; } while (get_weekday(cd) != wd); return cd; } CONSTEXPR_F int get_yearday(const civil_day& cd) noexcept { return static_cast(cd - civil_day(civil_year(cd))) + 1; } //////////////////////////////////////////////////////////////////////// std::ostream& operator<<(std::ostream& os, const civil_year& y); std::ostream& operator<<(std::ostream& os, const civil_month& m); std::ostream& operator<<(std::ostream& os, const civil_day& d); std::ostream& operator<<(std::ostream& os, const civil_hour& h); std::ostream& operator<<(std::ostream& os, const civil_minute& m); std::ostream& operator<<(std::ostream& os, const civil_second& s); std::ostream& operator<<(std::ostream& os, weekday wd); } // namespace detail } // namespace cctz #undef CONSTEXPR_M #undef CONSTEXPR_F #undef CONSTEXPR_D #endif // CCTZ_CIVIL_TIME_DETAIL_H_ lubridate/src/cctz/include/zone_info_source.h0000644000176200001440000000604713263152652021135 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CCTZ_ZONE_INFO_SOURCE_H_ #define CCTZ_ZONE_INFO_SOURCE_H_ #include #include #include #include namespace cctz { // A stdio-like interface for providing zoneinfo data for a particular zone. class ZoneInfoSource { public: virtual ~ZoneInfoSource() {} virtual std::size_t Read(void* ptr, std::size_t size) = 0; // like fread() virtual int Skip(std::size_t offset) = 0; // like fseek() }; } // namespace cctz namespace cctz_extension { // A function-pointer type for a factory that returns a ZoneInfoSource // given the name of a time zone and a fallback factory. Returns null // when the data for the named zone cannot be found. using ZoneInfoSourceFactory = std::unique_ptr (*)( const std::string&, const std::function( const std::string&)>&); // The user can control the mapping of zone names to zoneinfo data by // providing a definition for cctz_extension::zone_info_source_factory. // For example, given functions my_factory() and my_other_factory() that // can return a ZoneInfoSource for a named zone, we could inject them into // cctz::load_time_zone() with: // // namespace cctz_extension { // namespace { // std::unique_ptr CustomFactory( // const std::string& name, // const std::function( // const std::string& name)>& fallback_factory) { // if (auto zip = my_factory(name)) return zip; // if (auto zip = fallback_factory(name)) return zip; // if (auto zip = my_other_factory(name)) return zip; // return nullptr; // } // } // namespace // ZoneInfoSourceFactory zone_info_source_factory = CustomFactory; // } // namespace cctz_extension // // This might be used, say, to use zoneinfo data embedded in the program, // or read from a (possibly compressed) file archive, or both. // // cctz_extension::zone_info_source_factory() will be called: // (1) from the same thread as the cctz::load_time_zone() call, // (2) only once for any zone name, and // (3) serially (i.e., no concurrent execution). // // The fallback factory obtains zoneinfo data by reading files in ${TZDIR}, // and it is used automatically when no zone_info_source_factory definition // is linked into the program. extern ZoneInfoSourceFactory zone_info_source_factory; } // namespace cctz_extension #endif // CCTZ_ZONE_INFO_SOURCE_H_ lubridate/src/cctz/include/time_zone.h0000644000176200001440000003166013263152652017557 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // A library for translating between absolute times (represented by // std::chrono::time_points of the std::chrono::system_clock) and civil // times (represented by cctz::civil_second) using the rules defined by // a time zone (cctz::time_zone). #ifndef CCTZ_TIME_ZONE_H_ #define CCTZ_TIME_ZONE_H_ #include #include #include #include #include "civil_time.h" namespace cctz { // Convenience aliases. Not intended as public API points. template using time_point = std::chrono::time_point; using sys_seconds = std::chrono::duration; namespace detail { template inline std::pair, D> split_seconds(const time_point& tp) { auto sec = std::chrono::time_point_cast(tp); auto sub = tp - sec; if (sub.count() < 0) { sec -= sys_seconds(1); sub += sys_seconds(1); } return {sec, std::chrono::duration_cast(sub)}; } inline std::pair, sys_seconds> split_seconds(const time_point& tp) { return {tp, sys_seconds(0)}; } } // namespace detail // cctz::time_zone is an opaque, small, value-type class representing a // geo-political region within which particular rules are used for mapping // between absolute and civil times. Time zones are named using the TZ // identifiers from the IANA Time Zone Database, such as "America/Los_Angeles" // or "Australia/Sydney". Time zones are created from factory functions such // as load_time_zone(). Note: strings like "PST" and "EDT" are not valid TZ // identifiers. // // Example: // cctz::time_zone utc = cctz::utc_time_zone(); // cctz::time_zone pst = cctz::fixed_time_zone(std::chrono::hours(-8)); // cctz::time_zone loc = cctz::local_time_zone(); // cctz::time_zone lax; // if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... } // // See also: // - http://www.iana.org/time-zones // - http://en.wikipedia.org/wiki/Zoneinfo class time_zone { public: time_zone() = default; // Equivalent to UTC time_zone(const time_zone&) = default; time_zone& operator=(const time_zone&) = default; std::string name() const; // An absolute_lookup represents the civil time (cctz::civil_second) within // this time_zone at the given absolute time (time_point). There are // additionally a few other fields that may be useful when working with // older APIs, such as std::tm. // // Example: // const cctz::time_zone tz = ... // const auto tp = std::chrono::system_clock::now(); // const cctz::time_zone::absolute_lookup al = tz.lookup(tp); struct absolute_lookup { civil_second cs; // Note: The following fields exist for backward compatibility with older // APIs. Accessing these fields directly is a sign of imprudent logic in // the calling code. Modern time-related code should only access this data // indirectly by way of cctz::format(). int offset; // civil seconds east of UTC bool is_dst; // is offset non-standard? const char* abbr; // time-zone abbreviation (e.g., "PST") }; absolute_lookup lookup(const time_point& tp) const; template absolute_lookup lookup(const time_point& tp) const { return lookup(detail::split_seconds(tp).first); } // A civil_lookup represents the absolute time(s) (time_point) that // correspond to the given civil time (cctz::civil_second) within this // time_zone. Usually the given civil time represents a unique instant // in time, in which case the conversion is unambiguous. However, // within this time zone, the given civil time may be skipped (e.g., // during a positive UTC offset shift), or repeated (e.g., during a // negative UTC offset shift). To account for these possibilities, // civil_lookup is richer than just a single time_point. // // In all cases the civil_lookup::kind enum will indicate the nature // of the given civil-time argument, and the pre, trans, and post // members will give the absolute time answers using the pre-transition // offset, the transition point itself, and the post-transition offset, // respectively (all three times are equal if kind == UNIQUE). If any // of these three absolute times is outside the representable range of a // time_point the field is set to its maximum/minimum value. // // Example: // cctz::time_zone lax; // if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... } // // // A unique civil time. // auto jan01 = lax.lookup(cctz::civil_second(2011, 1, 1, 0, 0, 0)); // // jan01.kind == cctz::time_zone::civil_lookup::UNIQUE // // jan01.pre is 2011/01/01 00:00:00 -0800 // // jan01.trans is 2011/01/01 00:00:00 -0800 // // jan01.post is 2011/01/01 00:00:00 -0800 // // // A Spring DST transition, when there is a gap in civil time. // auto mar13 = lax.lookup(cctz::civil_second(2011, 3, 13, 2, 15, 0)); // // mar13.kind == cctz::time_zone::civil_lookup::SKIPPED // // mar13.pre is 2011/03/13 03:15:00 -0700 // // mar13.trans is 2011/03/13 03:00:00 -0700 // // mar13.post is 2011/03/13 01:15:00 -0800 // // // A Fall DST transition, when civil times are repeated. // auto nov06 = lax.lookup(cctz::civil_second(2011, 11, 6, 1, 15, 0)); // // nov06.kind == cctz::time_zone::civil_lookup::REPEATED // // nov06.pre is 2011/11/06 01:15:00 -0700 // // nov06.trans is 2011/11/06 01:00:00 -0800 // // nov06.post is 2011/11/06 01:15:00 -0800 struct civil_lookup { enum civil_kind { UNIQUE, // the civil time was singular (pre == trans == post) SKIPPED, // the civil time did not exist (pre >= trans > post) REPEATED, // the civil time was ambiguous (pre < trans <= post) } kind; time_point pre; // uses the pre-transition offset time_point trans; // instant of civil-offset change time_point post; // uses the post-transition offset }; civil_lookup lookup(const civil_second& cs) const; class Impl; private: explicit time_zone(const Impl* impl) : impl_(impl) {} const Impl* impl_ = nullptr; }; // Relational operators. bool operator==(time_zone lhs, time_zone rhs); inline bool operator!=(time_zone lhs, time_zone rhs) { return !(lhs == rhs); } // Loads the named time zone. May perform I/O on the initial load. // If the name is invalid, or some other kind of error occurs, returns // false and "*tz" is set to the UTC time zone. bool load_time_zone(const std::string& name, time_zone* tz); // Returns a time_zone representing UTC. Cannot fail. time_zone utc_time_zone(); // Returns a time zone that is a fixed offset (seconds east) from UTC. // Note: If the absolute value of the offset is greater than 24 hours // you'll get UTC (i.e., zero offset) instead. time_zone fixed_time_zone(const sys_seconds& offset); // Returns a time zone representing the local time zone. Falls back to UTC. time_zone local_time_zone(); // Returns the civil time (cctz::civil_second) within the given time zone at // the given absolute time (time_point). Since the additional fields provided // by the time_zone::absolute_lookup struct should rarely be needed in modern // code, this convert() function is simpler and should be preferred. template inline civil_second convert(const time_point& tp, const time_zone& tz) { return tz.lookup(tp).cs; } // Returns the absolute time (time_point) that corresponds to the given civil // time within the given time zone. If the civil time is not unique (i.e., if // it was either repeated or non-existent), then the returned time_point is // the best estimate that preserves relative order. That is, this function // guarantees that if cs1 < cs2, then convert(cs1, tz) <= convert(cs2, tz). inline time_point convert(const civil_second& cs, const time_zone& tz) { const time_zone::civil_lookup cl = tz.lookup(cs); if (cl.kind == time_zone::civil_lookup::SKIPPED) return cl.trans; return cl.pre; } namespace detail { using femtoseconds = std::chrono::duration; std::string format(const std::string&, const time_point&, const femtoseconds&, const time_zone&); bool parse(const std::string&, const std::string&, const time_zone&, time_point*, femtoseconds*, std::string* err = nullptr); } // namespace detail // Formats the given time_point in the given cctz::time_zone according to // the provided format string. Uses strftime()-like formatting options, // with the following extensions: // // - %Ez - RFC3339-compatible numeric time zone (+hh:mm or -hh:mm) // - %E#S - Seconds with # digits of fractional precision // - %E*S - Seconds with full fractional precision (a literal '*') // - %E#f - Fractional seconds with # digits of precision // - %E*f - Fractional seconds with full precision (a literal '*') // - %E4Y - Four-character years (-999 ... -001, 0000, 0001 ... 9999) // // Note that %E0S behaves like %S, and %E0f produces no characters. In // contrast %E*f always produces at least one digit, which may be '0'. // // Note that %Y produces as many characters as it takes to fully render the // year. A year outside of [-999:9999] when formatted with %E4Y will produce // more than four characters, just like %Y. // // Tip: Format strings should include the UTC offset (e.g., %z or %Ez) so that // the resultng string uniquely identifies an absolute time. // // Example: // cctz::time_zone lax; // if (!cctz::load_time_zone("America/Los_Angeles", &lax)) { ... } // auto tp = cctz::convert(cctz::civil_second(2013, 1, 2, 3, 4, 5), lax); // std::string f = cctz::format("%H:%M:%S", tp, lax); // "03:04:05" // f = cctz::format("%H:%M:%E3S", tp, lax); // "03:04:05.000" template inline std::string format(const std::string& fmt, const time_point& tp, const time_zone& tz) { const auto p = detail::split_seconds(tp); const auto n = std::chrono::duration_cast(p.second); return detail::format(fmt, p.first, n, tz); } // Parses an input string according to the provided format string and // returns the corresponding time_point. Uses strftime()-like formatting // options, with the same extensions as cctz::format(), but with the // exceptions that %E#S is interpreted as %E*S, and %E#f as %E*f. // // %Y consumes as many numeric characters as it can, so the matching data // should always be terminated with a non-numeric. %E4Y always consumes // exactly four characters, including any sign. // // Unspecified fields are taken from the default date and time of ... // // "1970-01-01 00:00:00.0 +0000" // // For example, parsing a string of "15:45" (%H:%M) will return a time_point // that represents "1970-01-01 15:45:00.0 +0000". // // Note that parse() returns time instants, so it makes most sense to parse // fully-specified date/time strings that include a UTC offset (%z or %Ez). // // Note also that parse() only heeds the fields year, month, day, hour, // minute, (fractional) second, and UTC offset. Other fields, like weekday (%a // or %A), while parsed for syntactic validity, are ignored in the conversion. // // Date and time fields that are out-of-range will be treated as errors rather // than normalizing them like cctz::civil_second() would do. For example, it // is an error to parse the date "Oct 32, 2013" because 32 is out of range. // // A second of ":60" is normalized to ":00" of the following minute with // fractional seconds discarded. The following table shows how the given // seconds and subseconds will be parsed: // // "59.x" -> 59.x // exact // "60.x" -> 00.0 // normalized // "00.x" -> 00.x // exact // // Errors are indicated by returning false. // // Example: // const cctz::time_zone tz = ... // std::chrono::system_clock::time_point tp; // if (cctz::parse("%Y-%m-%d", "2015-10-09", tz, &tp)) { // ... // } template inline bool parse(const std::string& fmt, const std::string& input, const time_zone& tz, time_point* tpp) { time_point sec; detail::femtoseconds fs; const bool b = detail::parse(fmt, input, tz, &sec, &fs); if (b) { // TODO: Return false if unrepresentable as a time_point. *tpp = std::chrono::time_point_cast(sec); *tpp += std::chrono::duration_cast(fs); } return b; } } // namespace cctz #endif // CCTZ_TIME_ZONE_H_ lubridate/src/cctz/include/civil_time.h0000644000176200001440000003203613263152652017710 0ustar liggesusers// Copyright 2016 Google Inc. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #ifndef CCTZ_CIVIL_TIME_H_ #define CCTZ_CIVIL_TIME_H_ #include "civil_time_detail.h" namespace cctz { // The term "civil time" refers to the legally recognized human-scale time // that is represented by the six fields YYYY-MM-DD hh:mm:ss. Modern-day civil // time follows the Gregorian Calendar and is a time-zone-independent concept. // A "date" is perhaps the most common example of a civil time (represented in // this library as cctz::civil_day). This library provides six classes and a // handful of functions that help with rounding, iterating, and arithmetic on // civil times while avoiding complications like daylight-saving time (DST). // // The following six classes form the core of this civil-time library: // // * civil_second // * civil_minute // * civil_hour // * civil_day // * civil_month // * civil_year // // Each class is a simple value type with the same interface for construction // and the same six accessors for each of the civil fields (year, month, day, // hour, minute, and second, aka YMDHMS). These classes differ only in their // alignment, which is indicated by the type name and specifies the field on // which arithmetic operates. // // Each class can be constructed by passing up to six optional integer // arguments representing the YMDHMS fields (in that order) to the // constructor. Omitted fields are assigned their minimum valid value. Hours, // minutes, and seconds will be set to 0, month and day will be set to 1, and // since there is no minimum valid year, it will be set to 1970. So, a // default-constructed civil-time object will have YMDHMS fields representing // "1970-01-01 00:00:00". Fields that are out-of-range are normalized (e.g., // October 32 -> November 1) so that all civil-time objects represent valid // values. // // Each civil-time class is aligned to the civil-time field indicated in the // class's name after normalization. Alignment is performed by setting all the // inferior fields to their minimum valid value (as described above). The // following are examples of how each of the six types would align the fields // representing November 22, 2015 at 12:34:56 in the afternoon. (Note: the // string format used here is not important; it's just a shorthand way of // showing the six YMDHMS fields.) // // civil_second 2015-11-22 12:34:56 // civil_minute 2015-11-22 12:34:00 // civil_hour 2015-11-22 12:00:00 // civil_day 2015-11-22 00:00:00 // civil_month 2015-11-01 00:00:00 // civil_year 2015-01-01 00:00:00 // // Each civil-time type performs arithmetic on the field to which it is // aligned. This means that adding 1 to a civil_day increments the day field // (normalizing as necessary), and subtracting 7 from a civil_month operates // on the month field (normalizing as necessary). All arithmetic produces a // valid civil time. Difference requires two similarly aligned civil-time // objects and returns the scalar answer in units of the objects' alignment. // For example, the difference between two civil_hour objects will give an // answer in units of civil hours. // // In addition to the six civil-time types just described, there are // a handful of helper functions and algorithms for performing common // calculations. These are described below. // // Note: In C++14 and later, this library is usable in a constexpr context. // // CONSTRUCTION: // // Each of the civil-time types can be constructed in two ways: by directly // passing to the constructor up to six (optional) integers representing the // YMDHMS fields, or by copying the YMDHMS fields from a differently aligned // civil-time type. // // civil_day default_value; // 1970-01-01 00:00:00 // // civil_day a(2015, 2, 3); // 2015-02-03 00:00:00 // civil_day b(2015, 2, 3, 4, 5, 6); // 2015-02-03 00:00:00 // civil_day c(2015); // 2015-01-01 00:00:00 // // civil_second ss(2015, 2, 3, 4, 5, 6); // 2015-02-03 04:05:06 // civil_minute mm(ss); // 2015-02-03 04:05:00 // civil_hour hh(mm); // 2015-02-03 04:00:00 // civil_day d(hh); // 2015-02-03 00:00:00 // civil_month m(d); // 2015-02-01 00:00:00 // civil_year y(m); // 2015-01-01 00:00:00 // // m = civil_month(y); // 2015-01-01 00:00:00 // d = civil_day(m); // 2015-01-01 00:00:00 // hh = civil_hour(d); // 2015-01-01 00:00:00 // mm = civil_minute(hh); // 2015-01-01 00:00:00 // ss = civil_second(mm); // 2015-01-01 00:00:00 // // ALIGNMENT CONVERSION: // // The alignment of a civil-time object cannot change, but the object may be // used to construct a new object with a different alignment. This is referred // to as "realigning". When realigning to a type with the same or more // precision (e.g., civil_day -> civil_second), the conversion may be // performed implicitly since no information is lost. However, if information // could be discarded (e.g., civil_second -> civil_day), the conversion must // be explicit at the call site. // // void fun(const civil_day& day); // // civil_second cs; // fun(cs); // Won't compile because data may be discarded // fun(civil_day(cs)); // OK: explicit conversion // // civil_day cd; // fun(cd); // OK: no conversion needed // // civil_month cm; // fun(cm); // OK: implicit conversion to civil_day // // NORMALIZATION: // // Integer arguments passed to the constructor may be out-of-range, in which // case they are normalized to produce a valid civil-time object. This enables // natural arithmetic on constructor arguments without worrying about the // field's range. Normalization guarantees that there are no invalid // civil-time objects. // // civil_day d(2016, 10, 32); // Out-of-range day; normalized to 2016-11-01 // // Note: If normalization is undesired, you can signal an error by comparing // the constructor arguments to the normalized values returned by the YMDHMS // properties. // // PROPERTIES: // // All civil-time types have accessors for all six of the civil-time fields: // year, month, day, hour, minute, and second. Recall that fields inferior to // the type's aligment will be set to their minimum valid value. // // civil_day d(2015, 6, 28); // // d.year() == 2015 // // d.month() == 6 // // d.day() == 28 // // d.hour() == 0 // // d.minute() == 0 // // d.second() == 0 // // COMPARISON: // // Comparison always considers all six YMDHMS fields, regardless of the type's // alignment. Comparison between differently aligned civil-time types is // allowed. // // civil_day feb_3(2015, 2, 3); // 2015-02-03 00:00:00 // civil_day mar_4(2015, 3, 4); // 2015-03-04 00:00:00 // // feb_3 < mar_4 // // civil_year(feb_3) == civil_year(mar_4) // // civil_second feb_3_noon(2015, 2, 3, 12, 0, 0); // 2015-02-03 12:00:00 // // feb_3 < feb_3_noon // // feb_3 == civil_day(feb_3_noon) // // // Iterates all the days of February 2015. // for (civil_day d(2015, 2, 1); d < civil_month(2015, 3); ++d) { // // ... // } // // STREAMING: // // Each civil-time type may be sent to an output stream using operator<<(). // The output format follows the pattern "YYYY-MM-DDThh:mm:ss" where fields // inferior to the type's alignment are omitted. // // civil_second cs(2015, 2, 3, 4, 5, 6); // std::cout << cs << "\n"; // Outputs: 2015-02-03T04:05:06 // // civil_day cd(cs); // std::cout << cd << "\n"; // Outputs: 2015-02-03 // // civil_year cy(cs); // std::cout << cy << "\n"; // Outputs: 2015 // // ARITHMETIC: // // Civil-time types support natural arithmetic operators such as addition, // subtraction, and difference. Arithmetic operates on the civil-time field // indicated in the type's name. Difference requires arguments with the same // alignment and returns the answer in units of the alignment. // // civil_day a(2015, 2, 3); // ++a; // 2015-02-04 00:00:00 // --a; // 2015-02-03 00:00:00 // civil_day b = a + 1; // 2015-02-04 00:00:00 // civil_day c = 1 + b; // 2015-02-05 00:00:00 // int n = c - a; // n = 2 (civil days) // int m = c - civil_month(c); // Won't compile: different types. // // EXAMPLE: Adding a month to January 31. // // One of the classic questions that arises when considering a civil-time // library (or a date library or a date/time library) is this: "What happens // when you add a month to January 31?" This is an interesting question // because there could be a number of possible answers: // // 1. March 3 (or 2 if a leap year). This may make sense if the operation // wants the equivalent of February 31. // 2. February 28 (or 29 if a leap year). This may make sense if the operation // wants the last day of January to go to the last day of February. // 3. Error. The caller may get some error, an exception, an invalid date // object, or maybe false is returned. This may make sense because there is // no single unambiguously correct answer to the question. // // Practically speaking, any answer that is not what the programmer intended // is the wrong answer. // // This civil-time library avoids the problem by making it impossible to ask // ambiguous questions. All civil-time objects are aligned to a particular // civil-field boundary (such as aligned to a year, month, day, hour, minute, // or second), and arithmetic operates on the field to which the object is // aligned. This means that in order to "add a month" the object must first be // aligned to a month boundary, which is equivalent to the first day of that // month. // // Of course, there are ways to compute an answer the question at hand using // this civil-time library, but they require the programmer to be explicit // about the answer they expect. To illustrate, let's see how to compute all // three of the above possible answers to the question of "Jan 31 plus 1 // month": // // const civil_day d(2015, 1, 31); // // // Answer 1: // // Add 1 to the month field in the constructor, and rely on normalization. // const auto ans_normalized = civil_day(d.year(), d.month() + 1, d.day()); // // ans_normalized == 2015-03-03 (aka Feb 31) // // // Answer 2: // // Add 1 to month field, capping to the end of next month. // const auto next_month = civil_month(d) + 1; // const auto last_day_of_next_month = civil_day(next_month + 1) - 1; // const auto ans_capped = std::min(ans_normalized, last_day_of_next_month); // // ans_capped == 2015-02-28 // // // Answer 3: // // Signal an error if the normalized answer is not in next month. // if (civil_month(ans_normalized) != next_month) { // // error, month overflow // } // using civil_year = detail::civil_year; using civil_month = detail::civil_month; using civil_day = detail::civil_day; using civil_hour = detail::civil_hour; using civil_minute = detail::civil_minute; using civil_second = detail::civil_second; // An enum class with members monday, tuesday, wednesday, thursday, friday, // saturday, and sunday. These enum values may be sent to an output stream // using operator<<(). The result is the full weekday name in English with a // leading capital letter. // // weekday wd = weekday::thursday; // std::cout << wd << "\n"; // Outputs: Thursday // using detail::weekday; // Returns the weekday for the given civil_day. // // civil_day a(2015, 8, 13); // weekday wd = get_weekday(a); // wd == weekday::thursday // using detail::get_weekday; // Returns the civil_day that strictly follows or precedes the given // civil_day, and that falls on the given weekday. // // For example, given: // // August 2015 // Su Mo Tu We Th Fr Sa // 1 // 2 3 4 5 6 7 8 // 9 10 11 12 13 14 15 // 16 17 18 19 20 21 22 // 23 24 25 26 27 28 29 // 30 31 // // civil_day a(2015, 8, 13); // get_weekday(a) == weekday::thursday // civil_day b = next_weekday(a, weekday::thursday); // b = 2015-08-20 // civil_day c = prev_weekday(a, weekday::thursday); // c = 2015-08-06 // // civil_day d = ... // // Gets the following Thursday if d is not already Thursday // civil_day thurs1 = prev_weekday(d, weekday::thursday) + 7; // // Gets the previous Thursday if d is not already Thursday // civil_day thurs2 = next_weekday(d, weekday::thursday) - 7; // using detail::next_weekday; using detail::prev_weekday; // Returns the day-of-year for the given civil_day. // // civil_day a(2015, 1, 1); // int yd_jan_1 = get_yearday(a); // yd_jan_1 = 1 // civil_day b(2015, 12, 31); // int yd_dec_31 = get_yearday(b); // yd_dec_31 = 365 // using detail::get_yearday; } // namespace cctz #endif // CCTZ_CIVIL_TIME_H_ lubridate/NAMESPACE0000644000176200001440000001325413236356705013463 0ustar liggesusers# Generated by roxygen2: do not edit by hand S3method(as.POSIXct,fts) S3method(as.POSIXct,irts) S3method(as.POSIXct,timeSeries) S3method(as.POSIXct,xts) S3method(as.POSIXct,zoo) S3method(as.POSIXlt,fts) S3method(as.POSIXlt,irts) S3method(as.POSIXlt,timeSeries) S3method(as.POSIXlt,tis) S3method(as.POSIXlt,xts) S3method(as.POSIXlt,zoo) S3method(as.list,Interval) S3method(date,Period) S3method(date,default) S3method(decimal_date,default) S3method(decimal_date,zoo) S3method(dst,default) S3method(format,Duration) S3method(format,Interval) S3method(format,Period) S3method(hour,Period) S3method(hour,default) S3method(mday,Period) S3method(mday,default) S3method(minute,Period) S3method(minute,default) S3method(month,Period) S3method(month,default) S3method(month,numeric) S3method(months,numeric) S3method(qday,default) S3method(reclass_date,Date) S3method(reclass_date,POSIXct) S3method(reclass_date,POSIXlt) S3method(reclass_date,chron) S3method(reclass_date,ti) S3method(reclass_date,timeDate) S3method(second,Period) S3method(second,default) S3method(summary,Duration) S3method(summary,Interval) S3method(summary,Period) S3method(tz,default) S3method(tz,irts) S3method(tz,timeSeries) S3method(tz,zoo) S3method(unique,Interval) S3method(update,Date) S3method(update,POSIXt) S3method(wday,default) S3method(wday,numeric) S3method(xtfrm,Period) S3method(yday,default) S3method(year,Period) S3method(year,default) export("%--%") export("%m+%") export("%m-%") export("%within%") export("date<-") export("day<-") export("hour<-") export("int_end<-") export("int_start<-") export("mday<-") export("minute<-") export("month<-") export("qday<-") export("second<-") export("tz<-") export("wday<-") export("week<-") export("yday<-") export("year<-") export(add_with_rollback) export(am) export(as.difftime) export(as.duration) export(as.interval) export(as.period) export(as_date) export(as_datetime) export(ceiling_date) export(date) export(date_decimal) export(day) export(days) export(days_in_month) export(ddays) export(decimal_date) export(dhours) export(dmicroseconds) export(dmilliseconds) export(dminutes) export(dmy) export(dmy_h) export(dmy_hm) export(dmy_hms) export(dnanoseconds) export(dpicoseconds) export(dseconds) export(dst) export(duration) export(dweeks) export(dyears) export(dym) export(edays) export(ehours) export(emicroseconds) export(emilliseconds) export(eminutes) export(enanoseconds) export(epicoseconds) export(epiweek) export(epiyear) export(eseconds) export(eweeks) export(eyears) export(fast_strptime) export(fit_to_timeline) export(floor_date) export(force_tz) export(force_tzs) export(guess_formats) export(here) export(hm) export(hms) export(hour) export(hours) export(int_aligns) export(int_diff) export(int_end) export(int_flip) export(int_length) export(int_overlaps) export(int_shift) export(int_standardize) export(int_start) export(intersect) export(interval) export(is.Date) export(is.POSIXct) export(is.POSIXlt) export(is.POSIXt) export(is.difftime) export(is.duration) export(is.instant) export(is.interval) export(is.period) export(is.timepoint) export(is.timespan) export(isoweek) export(isoyear) export(leap_year) export(local_time) export(make_date) export(make_datetime) export(make_difftime) export(mday) export(mdy) export(mdy_h) export(mdy_hm) export(mdy_hms) export(microseconds) export(milliseconds) export(minute) export(minutes) export(month) export(ms) export(myd) export(nanoseconds) export(new_difftime) export(new_duration) export(new_interval) export(new_period) export(now) export(olson_time_zones) export(origin) export(parse_date_time) export(parse_date_time2) export(period) export(period_to_seconds) export(picoseconds) export(pm) export(pretty_dates) export(qday) export(quarter) export(reclass_date) export(reclass_timespan) export(rollback) export(round_date) export(second) export(seconds) export(seconds_to_period) export(semester) export(setdiff) export(stamp) export(stamp_date) export(stamp_time) export(time_length) export(today) export(tz) export(union) export(wday) export(week) export(weeks) export(with_tz) export(yday) export(ydm) export(ydm_h) export(ydm_hm) export(ydm_hms) export(year) export(years) export(ymd) export(ymd_h) export(ymd_hm) export(ymd_hms) export(yq) exportClasses(Duration) exportClasses(Interval) exportClasses(Period) exportClasses(Timespan) exportMethods("$") exportMethods("$<-") exportMethods("%%") exportMethods("%/%") exportMethods("%m+%") exportMethods("%m-%") exportMethods("*") exportMethods("+") exportMethods("-") exportMethods("/") exportMethods("[") exportMethods("[<-") exportMethods("[[") exportMethods("[[<-") exportMethods("date<-") exportMethods("day<-") exportMethods("hour<-") exportMethods("minute<-") exportMethods("month<-") exportMethods("second<-") exportMethods("year<-") exportMethods(Arith) exportMethods(Compare) exportMethods(as.character) exportMethods(as.difftime) exportMethods(as.interval) exportMethods(as.numeric) exportMethods(as_date) exportMethods(as_datetime) exportMethods(c) exportMethods(intersect) exportMethods(reclass_timespan) exportMethods(rep) exportMethods(setdiff) exportMethods(show) exportMethods(union) import(stringr) importFrom(Rcpp,sourceCpp) importFrom(methods,"coerce<-") importFrom(methods,"slot<-") importFrom(methods,Arith) importFrom(methods,Compare) importFrom(methods,allNames) importFrom(methods,callGeneric) importFrom(methods,initialize) importFrom(methods,is) importFrom(methods,new) importFrom(methods,setClass) importFrom(methods,setGeneric) importFrom(methods,show) importFrom(methods,slot) importFrom(methods,slotNames) importFrom(methods,validObject) importFrom(stats,na.omit) importFrom(stats,setNames) importFrom(stats,update) importFrom(utils,packageVersion) importFrom(utils,read.delim) useDynLib(lubridate, .registration=TRUE) lubridate/NEWS.md0000644000176200001440000010164013263152547013335 0ustar liggesusersVersion 1.7.4 ============= ### NEW FEATURES * [#658](https://github.com/tidyverse/lubridate/issues/658) `%within%` now accepts a list of intervals, in which case an instant is checked if it occurs within any of the supplied intervals. ### CHANGES * [#661](https://github.com/tidyverse/lubridate/issues/661) Throw error on invalid multi-unit rounding. * [#633](https://github.com/tidyverse/lubridate/issues/633) `%%` on intervals relies on `%m+` arithmetic and doesn't produce NAs when intermediate computations result in non-existent dates. * `tz()` always returns "UTC" when `tzone` attribute cannot be inferred. ### BUG FIXES * [#664](https://github.com/tidyverse/lubridate/issues/664) Fix lookup of period functions in `as.period` Version 1.7.3 ============= ### BUG FIXES * [#643](https://github.com/tidyverse/lubridate/issues/643), [#640](https://github.com/tidyverse/lubridate/issues/640), [#645](https://github.com/tidyverse/lubridate/issues/645) Fix faulty caching of system timezone. Version 1.7.2 ============= ### NEW FEATURES * Durations, Periods and difftimes are now comparable with each other. * `interval` constructor accepts start and end character vectors in ISO 8601 format * [#362](https://github.com/tidyverse/lubridate/issues/362) Add support for ISO 8601 formats in interval constructor * [#622](https://github.com/tidyverse/lubridate/issues/622) Add support for ISO 8601 formats in periods and durations constructor ### CHANGES * Correct license to the originally intended GPL (>= 2) ### BUG FIXES * [#605](https://github.com/tidyverse/lubridate/issues/605) Fix wrong ceiling of days during DST transition. * [#607](https://github.com/tidyverse/lubridate/issues/607) Re-instate `format` argument to `as_date` and `as_datetime` (regression in v1.7.1) * Fix intersection of intervals with missing values. * Fix UBSAN errors in update.cpp Version 1.7.1 ============= ### BUG FIXES * [#575](https://github.com/tidyverse/lubridate/issues/598), [#600](https://github.com/tidyverse/lubridate/issues/600), [#602](https://github.com/tidyverse/lubridate/issues/602) Fix zoneinfo lookup on windows and solaris. * [#598](https://github.com/tidyverse/lubridate/issues/598) Fix broken parsing of `ymd_hms` strings by `as_date`. * [#597](https://github.com/tidyverse/lubridate/issues/597) Fix broken parsing of `ymd` strings by `as_datetime`. Version 1.7.0 ============= ### NEW FEATURES * Reduced memory footprint on `trunc_multi_unit` so that it overwrites the vector argument `x` versus making a new vector `y`. * [#438](https://github.com/tidyverse/lubridate/issues/438) New function `force_tzs` for "enforcement" of heterogeneous time zones. * [#438](https://github.com/tidyverse/lubridate/issues/438) New function `local_time` for the retrieval of local day time in different time zones. * [#560](https://github.com/tidyverse/lubridate/issues/560) New argument `cutoff_2000` for parsing functions to indicate 20th century cutoff for `y` format. * [#257](https://github.com/tidyverse/lubridate/issues/257) New `week_start` parameter in `wday` and `wday<-` to set week start. * [#401](https://github.com/tidyverse/lubridate/issues/401) New parameter `locale` in `wday`. Labels of the returned factors (when `label=TRUE`) now respect current locale. * [#485](https://github.com/tidyverse/lubridate/pull/485) `quarter` gained a new argument `fiscal_start` to address the issue of different fiscal conventions. * [#492](https://github.com/tidyverse/lubridate/issues/492) New functions `epiweek` and `epiyear`. * [#508](https://github.com/tidyverse/lubridate/pull/508) New parameter `locale` in `month`. Labels of the returned factors (when `label=TRUE`) now respect current locale. * [#509](https://github.com/tidyverse/lubridate/issues/509) New parameter `week_start` to `floor_date`, `ceiling_date` and `round_date`. * [#519](https://github.com/tidyverse/lubridate/issues/519) Support fractional units in duration and period string constructors. * [#502](https://github.com/tidyverse/lubridate/issues/502) Support rounding to fractions of a seconds. * [#529](https://github.com/tidyverse/lubridate/issues/529) Internal parser now ignores the case of alpha months (B format) * [#535](https://github.com/tidyverse/lubridate/issues/535) Rounding to `season` is now supported. * [#536](https://github.com/tidyverse/lubridate/issues/536) `as_date` and `as_datetime` now understand character vectors. * New parsing parameters to `parse_date_time` - `train=TRUE` and `drop=FALSE` which allow more refined control of the format guessing. Formats are no longer dropped in the process by default, process which resulted in surprising behavior on several occasions ([#516](https://github.com/tidyverse/lubridate/issues/516),[#308](https://github.com/tidyverse/lubridate/issues/308),[#307](https://github.com/tidyverse/lubridate/issues/307)). ### CHANGES * [#401](https://github.com/tidyverse/lubridate/issues/401) **[Breaking Change]** Labels returned by `wday` and `month` are now in current locale. The abbreviated labels in English locales have been changed to standard abbreviations (Tues -> Tue, Thurs -> Thu etc.). * [#469](https://github.com/tidyverse/lubridate/issues/469) Throw warning in `with_tz` on invalid timezone. * [#572](https://github.com/tidyverse/lubridate/issues/572) `B` and `b` formats no longer match numeric months. This corresponds to the original intent, and was always documented as such. ### BUG FIXES * [#314](https://github.com/tidyverse/lubridate/issues/314), [#407](https://github.com/tidyverse/lubridate/issues/407), [#499](https://github.com/tidyverse/lubridate/issues/499) Make `days`, `dhours`, `round_date` work when the methods package is not loaded. * [#543](https://github.com/tidyverse/lubridate/issues/543) Make `wday` work on character inputs as it is the case with all other day accessors. * [#566](https://github.com/tidyverse/lubridate/issues/566) Comparing durations and periods no-longer infloops. * [#556](https://github.com/tidyverse/lubridate/issues/556) Fix incorrect scoring of `y` format when it's the last in format order (as in `mdy`). * [#584](https://github.com/tidyverse/lubridate/issues/584) Fix interval by period division. * [#559](https://github.com/tidyverse/lubridate/issues/559) Parsing of alpha-months in English locales now drops correctly to low level C parsing. Thus, parsing with multiple orders containing `m` and `b` formats now works correctly. * [#570](https://github.com/tidyverse/lubridate/issues/570), [#574](https://github.com/tidyverse/lubridate/issues/574) Fix broken `date()` when called with missing argument. * [#567](https://github.com/tidyverse/lubridate/issues/567) Fix year update and rounding for leap years. * [#545](https://github.com/tidyverse/lubridate/pull/545) Fix wrong locale selection in stamp. * [#466](https://github.com/tidyverse/lubridate/pull/466) Fix wrong formats within ymd_h family of functions. * [#472](https://github.com/tidyverse/lubridate/pull/472) Printing method for duration doesn't throw format error on fractional seconds. * [#475](https://github.com/tidyverse/lubridate/pull/475) character<> comparisons is no longer slow. * [#483](https://github.com/tidyverse/lubridate/pull/483) Fix add_duration_to_date error when duration first element is NA. * [#486](https://github.com/tidyverse/lubridate/issues/486) ceiling_date handles `NA` properly. * [#491](https://github.com/tidyverse/lubridate/issues/491) `make_datetime` respects `tz` argument and is much faster now. * [#507](https://github.com/tidyverse/lubridate/issues/507) Period and duration parsers now understand 0 units. * [#524](https://github.com/tidyverse/lubridate/pull/524) Correctly compute length of period in months (issue #490) * [#525](https://github.com/tidyverse/lubridate/pull/525) Fix to prevent `day<-`, `minute<-`, etc. from producing an error when length(x) is 0 (issue #517) * [#530](https://github.com/tidyverse/lubridate/issues/530) `parse_date_time` now throw warnings only for actual parsing errors (input with all NAs are silent) * [#534](https://github.com/tidyverse/lubridate/issues/534) Fix arithmetics with large numbers * [#554](https://github.com/tidyverse/lubridate/pull/554) Fix tests when running in non-English locales Version 1.6.0 ============= ### NEW FEATURES * [#464](https://github.com/hadley/lubridate/issues/464) New function `semester` to extract semesters form date-time objects. * [#459](https://github.com/hadley/lubridate/issues/459) Flexible C-level parsing for periods and durations has been implemented; `period` and `duration` constructors now accept string as first argument. Same parsing rules apply to the 'unit' parameter in rounding functions. * [#459](https://github.com/hadley/lubridate/issues/459) Comparison between character vectors and periods/durations is now possible. * [#287](https://github.com/hadley/lubridate/issues/287) C-level and derivative parsers now handle English months (%b and %B formats) irrespective of the current locale. * [#327](https://github.com/hadley/lubridate/issues/327) C-level and derivative parsers now handles English AM/PM indicator irrespective of the current locale. * [#417](https://github.com/hadley/lubridate/issues/417) `hms`, `hm`, `ms` gained new argument `roll=TRUE` which rolls minutes and seconds bigger than 59 towards higher units. * [#445](https://github.com/hadley/lubridate/issues/445) Division of intervals by periods is now accurate. * [#442](https://github.com/hadley/lubridate/issues/442) `round_date`, `floor_date` and `ceiling_date` now support rounding to multiple of units. * [#422](https://github.com/hadley/lubridate/issues/422) New parsing function `yq` for parsing most common version of quarter strings. * [#422](https://github.com/hadley/lubridate/issues/422) New format `q` for parsing quarters in all lubridate parsing functions. * [#441](https://github.com/hadley/lubridate/issues/441) Comparison between POSIXt and Date objects is now possible. * [#437](https://github.com/hadley/lubridate/issues/437) New function `as_datetime` to coerce to POSIXct object. A counterpart of `as_date`. * [#412](https://github.com/hadley/lubridate/issues/412) New function `make_date` to produce Date objects. A counterpart of `make_datetime`. * [#443](https://github.com/hadley/lubridate/issues/443) Behavior of `ceiling_date` for `Date` objects was changed to what most of the users expect. Rounding up by months now produces first day of the next months even for first day of the month. * [#268](https://github.com/hadley/lubridate/issues/268) `round_date`, `ceiling_date`, and `floor_date` now accept "quarter", "bimonth", and "halfyear" as `unit` options. * [#418](https://github.com/hadley/lubridate/issues/418) C level parsing functions understand 24:00:00 in datetime strings. ### CHANGES * Low letter specs for HMS (hms,hm,ms) in `parse_date_time` and related functions are now deprecated. * [#445](https://github.com/hadley/lubridate/issues/445) No more warning on occasional imprecise period length conversions. Imprecise arithmetics with periods is extensively documented. * `pretty.*` family of functions were renamed and are no longer exported. If you need to use them, use `lubridate:::pretty_*` versions. * `change_on_boundary` argument in `ceiling_date` does not allow for global option anymore. * `as.duration`, `as.numeric` don't show "only estimate" messages on conversion from periods. The occasional approximate conversion is documented and deemed common knowledge. * `as.numeric` with `unit="month"` now works on duration objects. * [#403](https://github.com/hadley/lubridate/issues/403) Update on `Date` objects now return `POSIXct` instead of `POSIXlt`. * [#411](https://github.com/hadley/lubridate/issues/411) format `mdy` or `myd` beginning with `"January"` or `"Jan"` now parsing correctly * `here` and `olson_time_zones` were deprecated in favor of `new` and base `OlsonNames` respectively. * Internally, S4 Compare and Ops generics were cleaned and simplified. * [#456](https://github.com/hadley/lubridate/issues/456) Evaluation output in documentation examples was removed. ### BUG FIXES * [#479](https://github.com/hadley/lubridate/issues/479) Fix the inconsistent behavior in `ceiling_date` when `unit = "week"` * [#463](https://github.com/hadley/lubridate/issues/463) Fix NA subscripting error in %m+% when rollback is involved. * [#462](https://github.com/hadley/lubridate/issues/462) Non-numeric or non-character arguments are disallowed as arguments to `period` and `duration` constructors. * [#458](https://github.com/hadley/lubridate/issues/458) When year is missing in parsing, return consistently year 0. * [#448](https://github.com/hadley/lubridate/issues/448) Correctly handle missing months and days in C parser. * [#450](https://github.com/hadley/lubridate/issues/450) Fix incorrect handling of DST gaps in `date_decimal` and `decimal_date`. * [#420](https://github.com/hadley/lubridate/issues/420) `as.numeric` correctly converts periods to (aproximate) numeric time lengths. Version 1.5.6 ============ ### NEW FEATURES * [#390](https://github.com/hadley/lubridate/issues/390) `ceiling_date` gains new argument `change_on_boundary` to allow ceiling on boundary of date-time objects. * C parser can now produce a list of date-time components suitable for POSIXlt constructors. * `parse_date_time2` and `fast_strptime` gain new `lt` argument to control type of output. * [#373](https://github.com/hadley/lubridate/issues/373) New `date` and `date<-` additions to the `year`, `month` etc family of accessors. * [#365](https://github.com/hadley/lubridate/issues/365) New very fast datetime constructor `make_datetime` (dropin replacement of `ISOdatetime`). * [#344](https://github.com/hadley/lubridate/issues/344) `force_tz` and `with_tz` can handle data.frames component-wise. * [#355](https://github.com/hadley/lubridate/issues/355) New `as_date` replacement of `as.Date` with more intuitive behavior with non-UTC timezones. * [#333](https://github.com/hadley/lubridate/issues/333) `hms` parsers now handle negative components. ### CHANGES * [#391](https://github.com/hadley/lubridate/issues/391) `ymd` family of functions return `Date` object when `tz` argument is NULL (new default) and POSIXct otherwise. * [#364](https://github.com/hadley/lubridate/issues/364) Remove epoch functions. * For consistency with `base:strptime` `fast_strptime` now returns `POSIXlt` object. That is, its `lt` argument defaults to `TRUE`. ### BUG FIXES * `interval` constructor treats timezones correctly and works with UTC whenever meaningful. * [#371](https://github.com/hadley/lubridate/issues/371) `as.period` correctly computes months with intervals spanning multiple years. * [#388](https://github.com/hadley/lubridate/issues/388) `time_length` and `add_with_rollback` now work correctly with missing intervals. * [#394](https://github.com/hadley/lubridate/issues/394) `fast_strptime` and `parse_date_time2` correctly treat non-UTC time zones. * [#399](https://github.com/hadley/lubridate/issues/399) `floor_date` and `round_date` are not preserving tz component for larger than day units Version 1.5.0 ============= ### NEW FEATURES * New `time_length` method. * Added `isoyear` function to line up with `isoweek`. * [#326](https://github.com/hadley/lubridate/issues/326) Added `exact = TRUE` option to `parse_date_time` for faster and much more flexible specification of formats. * New `simple` argument to `fit_to_timeline` and `update` methods mostly intended for internal use. * [#315](https://github.com/hadley/lubridate/issues/315) Implement `unique` method for `interval` class. * [#295](https://github.com/hadley/lubridate/issues/295) New args `preserve_hms` and `roll_to_first` in `rollback` function. * [#303](https://github.com/hadley/lubridate/issues/303) New `quarter` option in `floor_date` and friends. * [#348](https://github.com/hadley/lubridate/issues/348) New `as.list.Interval` S3 method. * [#278](https://github.com/hadley/lubridate/issues/278) Added settors and accessors for `qday` (quarter day). ### CHANGES * New maintainer Vitalie Spinu (@vspinu) * Time span constructors were re-factored; `new_interval`, `new_period`, `new_duration`, `new_difftime` were deprecated in favour of the more powerful `interval`, `period`, `duration` and `make_difftime` functions. * `eseconds`, `eminutes` etc. were deprecated in favour of `dsecons`, `dminutes` etc. * Many documentation improvements. * New testthat conventions are adopted. Tests are now in `test/testthat`. * Internally `isodate` was replaced with a much faster `parse_date_time2(paste(...))` alternative * [#325](https://github.com/hadley/lubridate/issues/325) `Lubridate`'s `trunc`, `ceiling` and `floor` functions have been optimised and now are relying on R's `trunc.POSIXct` whenever possible. * [#285](https://github.com/hadley/lubridate/issues/285) Algebraic computations with negative periods are behaving asymmetrically with respect to their positive counterparts. * Made necessary changes to accommodate new zoo-based `fst` objects. ### BUG FIXES * [#360](https://github.com/hadley/lubridate/issues/360) Fix c parser for Z (zulu) indicator. * [#322](https://github.com/hadley/lubridate/issues/322) Explicitly encode formatted string with `enc2utf8`. * [#302](https://github.com/hadley/lubridate/issues/302) Allow parsing long numbers such as 20140911000000 as date+time. * [#349](https://github.com/hadley/lubridate/issues/349) Fix broken interval -> period conversion. * [#336](https://github.com/hadley/lubridate/issues/336) Fix broken interval-> period conversion with negative diffs. * [#227](https://github.com/hadley/lubridate/issues/227) Treat "days" and "years" units specially for pretty.point. * [#286](https://github.com/hadley/lubridate/issues/286) %m+-% correctly handles dHMS period components. * [#323](https://github.com/hadley/lubridate/issues/323) Implement coercion methods for Duration class. * [#226](https://github.com/hadley/lubridate/issues/226) Propagate NAs in `int_standardize` * [#235](https://github.com/hadley/lubridate/issues/235) Fix integer division with months and years. * [#240](https://github.com/hadley/lubridate/issues/240) Make `ceiling_date` skip day light gap. * [#254](https://github.com/hadley/lubridate/issues/254) Don't preprocess a/A formats if expressly specified by the user. * [#289](https://github.com/hadley/lubridate/issues/289) Check for valid day-months combinations in C parser. * [#306](https://github.com/hadley/lubridate/issues/306) When needed double guess with `preproc_wday=T`. * [#308](https://github.com/hadley/lubridate/issues/308) Document sparce format guessing in `parse_date_time`. * [#313](https://github.com/hadley/lubridate/issues/313) Fixed and optimized `fit_to_timeline` function. * [#311](https://github.com/hadley/lubridate/issues/311) Always use UTC in `isoweek` computation * [#294](https://github.com/hadley/lubridate/issues/294) Don't use years in `seconds_to_period`. * Values on `$<-` assignment for periods are now properly recycled. * Correctly handle NA subscripting in `round_date`. Version 1.4.0 ============= ### CHANGES * [#219](//github.com/hadley/lubridate/issues/219) In `interval` use UTC when tzone is missing. * [#255](//github.com/hadley/lubridate/issues/255) Parse yy > 68 as 19yy to comply with `strptime`. ### BUG FIXES * [#266](//github.com/hadley/lubridate/issues/266) Include `time-zones.R` in `coercion.R`. * [#251](//github.com/hadley/lubridate/issues/251) Correct computation of weeks. * [#262](//github.com/hadley/lubridate/issues/262) Document that month boundary is the first second of the month. * [#270](//github.com/hadley/lubridate/issues/270) Add check for empty unit names in `standardise_lt_names`. * [#276](//github.com/hadley/lubridate/issues/276) Perform conversion in `as.period.period` if `unit != NULL`. * [#284](//github.com/hadley/lubridate/issues/284) Compute periods in `as.period.interval` without recurring to modulo arithmetic. * [#272](//github.com/hadley/lubridate/issues/272) Update examples for `hms`, `hm` and `ms` for new printing style. * [#236](//github.com/hadley/lubridate/issues/236) Don't allow zeros in month and day during parsing. * [#247](//github.com/hadley/lubridate/issues/247) Uninitialized index was mistakenly used in subseting. * [#229](//github.com/hadley/lubridate/issues/229) `guess_formats` now matches flex regexp first. * `dmilliseconds` now correctly returns a `Duration` object. * Fixed setdiff for discontinuous intervals. Version 1.3.3 ============= ### CHANGES * New low level C parser for numeric formats and two new front-end R functions parse_date_time2 and fast_strptime. The achieved speed up is 50-100x as compared to standard as.POSIXct and strptime functions. The user level parser functions of ymd_hms family drop to these C routines whenever plain numeric formats are detected. ### BUG FIXES * olson_time_zones now supports Solaris OS * infinite recursion on parsing non-existing leap times was fixed Version 1.3.2 ============= * Lubridate's s4 methods no longer use the representation argument, which has been deprecated in R 3.0.0 (see ?setClass). As a result, lubridate is no longer backwards compatible with R <3.0.0. Version 1.3.0 ============= ### CHANGES * v1.3.0. treats math with month and year Periods more consistently. If adding or subtracting n months would result in a non-existent date, lubridate will return an NA instead of a day in the following month or year. For example, `ymd("2013-01-31") + months(1)` will return `NA` instead of `2013-03-04` as in v1.2.0. `ymd("2012-02-29") + years(1)` will also return an `NA`. This rule change helps ensure that date + timespan - timespan = date (or NA). If you'd prefer that such arithmetic just returns the last day of the resulting month, see `%m+%` and `%m-%`. * update.POSIXct and update.POSIXlt have been rewritten to be 7x faster than their versions in v1.2.0. The speed gain is felt in `force_tz`, `with_tz`, `floor_date`, `ceiling_date`, `second<-`, `minute<-`, `hour<-`, `day<-`, `month<-`, `year<-`, and other functions that rely on update (such as math with Periods). * lubridate includes a Korean translation provided by http://korea.gnu.org/gnustats/ ### NEW FEATURES * lubridate parser and stamp functions now handle ISO8601 date format (e.g., 2013-01-24 19:39:07.880-06:00, 2013-01-24 19:39:07.880Z) * lubridate v1.3.0 comes with a new R vignette. see `browseVignettes("lubridate")` to view it. * The accessors `second`, `minute`, `hour`, `day`, `month`, `year` and the settors `second<-`, `minute<-`, `hour<-`, `day<-`, `month<-`, `year<-` now work on Period class objects * users can control which messages lubridate returns when parsing and estimating with the global option lubridate.verbose. Run `options(lubridate.verbose = TRUE)` to turn parsing messages on. Run `options(lubridate.verbose = FALSE)` to turn estimation and coercion messages off. * lubridate parser functions now propagate NA's just as as.POSIXct, strptime and other functions do. Previously lubridate's parse functions would only return an error. * added [[ and [[<- methods for INterval, Period and Duration class objects * added `%m+%` and `%m-%` methods for Interval and Duration class objects that throw useful errors. * `olson_time_zones` retreives a character vector is Olson-style time zone names to use in lubridate * summary methods for Interval, Period, and Duration classes * date_decimal converts a date written as a decimal of a year into a POSIXct date-time ### BUG FIXES * fixed bug in way update.POSIXct and update.POSIXlt handle dates that occur in the fall daylight savings overlap. update will choose the date-time closest to the original date time (on the timeline) when two identical clock times exist due to the DST overlap. * fixed bugs that created unintuitive results for `as.interval`, `int_overlaps`, `%within%` and the interval methods of `c`, `intersect`, `union`, `setdiff`, and `summary`. * parse functions, `as.interval`, `as.period` and `as.duration` now handlevectors of NA's without returning errors. * parsers better handle vectors of input that have more than 100 elements and many NAs * data frames that contain timespan objects with NAs in thme no longer fail toprint * `round_date`, `ceiling_date` and `update` now correctly handle input of length zero * `decimal_date` no longer returns NaN for first second of the year Version 1.2.0 ============= ### CHANGES * lubridate 1.2.0 is significantly faster than lubridate 1.1.0. This is largely thanks to a parser rewrite submitted by Vitalie Spinu. Thank you, Vitalie. Some metrics: - parser speed up - 60x faster - `with_tz` speed up - 15x faster - `force_tz` speed up - 3x faster * Development for 1.2.0 has also focused on improving the way we work with months. `rollback` rolls dates back to the last day of the previous month. provides more options for working with months. `days_in_month` finds the number of days in a date's month. And, `%m+%` and `%m-%` provide a new way to ### handle unequal month lengths while doing arithmetic. See NEW FEATURES for more details * date parsing can now parse multiple date formats within the same vector of date-times. Parsing can also recognize a greater variety of date-time formats as well as incomplete (truncated) date-times. Contributed by Vitalie Spinu. Thank you, Vitalie. * 1.2.0 introduces a new display format for periods. The display is more math and international friendly. * 1.2.0 transforms negative intervals into periods much more gracefully (e.g, - 3 days instead of -1 years, 11 months, and 27 days) * S3 update methods are now exported ### NEW FEATURES * `stamp` allows users to print dates in whatever form they like. Contributed by Vitalie Spinu. Thank you, Vitalie. * periods now handle fractional seconds. Contributed by Vitalie Spinu. Thank you, Vitalie. * date parsing can now parse multiple date formats within the same vector of date-times. Parsing can also recognize a greater variety of date-time formats as well as incomplete (truncated) date-times. Contributed by Vitalie Spinu. Thank you, Vitalie. * `sort`, `order`, `rank` and `xtfrm` now work with periods * `as.period.Interval` accepts a unit argument. `as.period` will convert intervals into periods no larger than the supplied unit. * `days_in_month` takes a date, returns the number of days in the date's month. Contributed by Richard Cotton. Thank you, Richard. * `%m+%` and `%m-%` perform addition and subtraction with months (and years) without rollover at the end of a month. These can be used in place of + and -. These can't be used with periods smaller than a month, which should be handled separately. An example of the new behavior: ymd("2010-01-31") %m+% months(1) # "2010-02-28 UTC" ymd("2010-01-31") + months(1) # "2010-03-03 UTC" ymd("2010-03-31") %m-% months(1) # "2010-02-28 UTC" ymd("2010-01-31") - months(1) # "2010-03-03 UTC" * `rollback` rolls a date back to the last day of the previous month. * `quarter` returns the fiscal quarter that a date occurs in. Like `quartes` in base R, but returns a numeric instead of a character string. ### BUG FIXES * date parsers now handle NAs * periods now handle NAs * `[<-` now correctly updates all elements of a period inside a vector, list, or data.frame * `period()` now works with unit = "weeks" * `ceiling_date` no longer rounds up if a date is already at a ceiling * the redundant (i.e, repeated) hour of fall daylight savings time now displays with the correct time zone * `update.POSIXct` and `update.POSIXlt` handle vectors that sum to zero in the days argument * the format method for periods, intervals and duration now accurately displays objects of length 0. Version 1.1.0 ============= ### CHANGES * lubridate no longer overwrites base R methods for +, - , *, /, %%, and %/%. To recreate the previous experience of subtracting two date times to create an interval, we've added the interval creation function %--%. * lubridate has moved to an S4 object system. Timespans, Intervals, Durations, and Periods have each been redefined as an S4 class with its own methods. * arithmetic operations will no longer perform implicit class changes between timespans. Users must explicitly state how and when they wish class changes to occur with as.period(), as.duration(), and as.interval(). This makes code written with lubridate more robust, as such implicit changes often did not produce consistent behavior across a variety of operations. It also allows lubridate to be less chatty with fewer console messages. lubridate does not need to explain what it is doing, because it no longer attempts to do things whose outcome would not be clear. On the other hand, arithmetic between multiple time classes will produce informative error messages. * the internal structure of lubridate R code has been reorganized at https://github.com/hadley/lubridate to make lubridate more development friendly. ### NEW FEATURES * intervals are now more useful and lubridate has more ways to manipulate them. Intervals can be created with %--%; modified with int_shift(), int_flip(), and int_standardize(); manipulated with intersect(), union(), and setdiff(); and used in logical tests with int_aligns(), int_overlaps(), and %within%. lubridate will no longer perform arithmetic between two intervals because the correct results of such operations is no more obvious than the correct result of adding two dates. Instead users are encouraged to use the new set operations or to directly modify intervals with int_start() and int_end(), which can also be used as settors. lubridate now supports negative intervals as well as positive intervals. Intervals also now display with a time zone. * Modulo methods for timespans have been changed to return a timespan. this allows modulo methods to be used with integer division in an intuitive manner, e.g. `a = a %/% b * b + a %% b` Users can still acheive a numerical result by using as.numeric() on input before performing modulo. * Periods, durations, and intervals can now all be put into a data frame. * Periods, durations, and intervals can be intuitively subset with $ and []. These operations also can be used as settors with <-. * The parsing functions and the as.period method for intervals are now slightly faster. * month<- and wday<- settors accept names as well as numbers * parsing functions now have a quiet argument to parse without messages and a tz argument to directly parse times into the desired time zone. * logical comparison methods now work for period objects. Version 0.2.6 ============= * use `test_package` to avoid incompatibility with current version of `testthat` * other minor fixes to pass `R CMD check` Version 0.2.5 ============= * added ymdThms() for parsing ISO 8061 formatted combned dates and times ### BUG FIXES * removed bug in parsing dates with "T" in them * modified as.period.interval() to display periods in positive units Version 0.2.4 ============= * Add citations to JSS article Version 0.2.3 ============= ### NEW FEATURES * ymd_hms(), hms(), and ms() functions can now parse dates that include decimal values in the seconds element. * milliseconds(), microseconds(), nanoseconds(), and picoseconds() create period objects of the specified lengths. dmilliseconds(), dmicroseconds(), dnanoseconds(), and dpicoseconds() make duration objects of the specified lengths. ### BUG FIXES * lubridate no longer overwrites months(), start(), and end() from base R. Start and end have been replaced with int_start() and int_end(). * lubridate imports plyr and stringr packages, instead of depending on them. Version 0.2.2 ============= ### NEW FEATURES * made division, modulo, and integer division operations compatible with difftimes * created c() methods for periods and durations ### BUG FIXES * fixed bug in division, modulo, and integer operations with timespans Version 0.2.1 ============= ### NEW FEATURES * created parsing functions ymd_hm ymd_h dmy_hms dmy_hm dmy_h mdy_hms mdy_hm mdy_h ydm_hms ydm_hm ydm_h, which operate in the same way as ymd_hms(). ### BUG FIXES * fixed bug in add_dates(). duration objects can now be successfully added to numeric objects. ----------- Version 0.2 =========== ### NEW FEATURES * division between timespans: each timespan class (durations, periods, intervals) can be divided by other timespans. For example, how many weeks are there between Halloween and Christmas?: (christmas - halloween) / weeks(1) * modulo operations between timespans * duration objects now have their own class and display format separate from difftimes * interval objects now use an improved data structure and have a cleaner display format * lubridate now loads its own namespace * math operations now automatically coerce interval objects to duration objects. Allows intervals to be used "right out of the box" without error messages. * created start() and end() functions for accessing and changing the boundary date-times of an interval * rep() methods for periods, intervals, and durations ### MINOR CHANGES * added a package help page with functions listed by purpose * eseconds(), eminutes(), etc. are aliased to dseconds(), dminutes(), etc. to make it easier to remember they are duration objects. * changed leap.years() to leap_years() to maintain consistent naming scheme ### BUG FIXES * rewrote as.period() to create only positive periods. * fixed rollover bug in update.POSIXct() * edited make_diff() to display in days when approporiate, not weeks lubridate/data/0000755000176200001440000000000013102460674013141 5ustar liggesuserslubridate/data/lakers.rda0000644000176200001440000041763013102102352015107 0ustar liggesusersBZh91AY&SYdSX*rؠʧjPZ}UU(h4 4i 2 p 4ѦA@4Ѧ241@4@h4@FU$4@MFzd RTx&F49.U?иE9\_G૛HU9$σeKi%Е.NN!D98W@⎭K #īU (W[#Wt]:Ge"A]_DBcg%!D2Ӓ5T*p&l⚸IA4T4Sg64eJN"Dk`JkE6(-8S,]h.}nvح"VM<(_(%8X';(l"b*6-ڊm![!FJ#hlT6RIălQJ &F6#bJDjB }}߽;s@x.n.J$UWN5*6Gu$* I'tn ު(s(S9Chs'҄tO-D}eIROq;G"xBM(G=T\)M}1)DR!ʪ'Lu '?RG$RեQ;)Iڊ\DC;&Q7S%NDS 9QMJmJ'xSA:'bڔnDR$c r0d*Z@i EuJKv0Rxv^P E9 )l޴N>= FK|_ٲ!Y V3D[#"% Х`]% 9BB./ -b)Lc4  5!*3R(ު¤qEQQK/6)Hf R 'pTD*Q,bH .JZ,FBlʩ2ZH֢%#duTԉqI Tg(*K /+bG*Q pH fIECphG`b1puA5{IOnJFˉ}:WNz=N/0,Eٱڡ $$PQX Lh۪"k*DZ2M+WdK 3J+k+z\j/X{Ƹ;j̢yvımwZ:4S b8털 Vbn˱+JzղZp`H(nbM'S!Mj[* <6G9Nld^+$jFc`1cT\WΣݭZŠu}wei9d0R8ZrQ.l(Tlmtafj f{QG϶\۲jҧI##Nz 6w!*IbLU4LTQr EV{OSSΕD2aY&&pC1ȄG>MַwQE-|umSުkEuݻ:"9=u#Z4q|,[pp%$5tJw׷5{ߓf}(W8vƗn͋t4 1QBTRp4ozz=ܹO:USXs5#r/vauܖx6#:/M9H".CMGNTlK-V.$2Jhzwv!m5u5BlARXDwd)x۬R#ifoqq]KGHkxzZJsMߛp|qO&GљCuL|3:![ŕ43-mc3%asnA{a"d++罦Z&d#D(Gj ".Yː xT 6<;:rL*'h#PٳSvtmդ'Uy5*[c3 5[PLk+bcm%A̍JkrĦI`(ISuχۮDnB),P1Q,Mɂ«RAϷéIWh;;=HD wo8^OqZR:Ք'{Mƣj/zd.CGG2Oyt95N'![5EI7XRF&42[;Dyyk\.( H%X7WkYh_yKyej3Ɵnh(goS2b륂|X#wQwѻH9:&+;2vBsڈm'wy/Gm}F5CeJr{TN.Eۨ=S ̊oRjLJchk9jAc#%0$md8!H I"3"m,pYwGk9>%<뛘ݻĝ;0ξ=ӓ[uzHhr8ltilIXsOfHGR>wGi c !V ڈy,̰1|+lvB${ᵪ&;nǷOF{Gֺ<؂2n;1.K9ƵXumc}{Eۚ'ivmLx0B(K9,SUA}egH׷\{vz}nqSnI$VDOFtU*u>F,W6O3tH(W&vlT;6 ̷  .I"cYZ)2 *A9#>(zw[ǒ6e7HQ{c;$8 9FH¦]wdirF-Y,qC]6y:DgՂ>I]7C/qeOSZemwgC^DۍCH>LEI8c@"t-c}vb8ri{vU*a.l6r2X[Q;m}CדSM\}vOY+/VI4m{wn[^YQ*n1@5HAXR]}<vZlNǶOq)ѻ.+Urrm;sv pA0q22Yo2mpȰO,XK] ABs%1cNL.YEkƭuHYS #b(1a ̱b+2m8r9/*B 8(I1L#s#u/Q;]SQo/8!k+D̛z zX]y}ϓr :KI8#HZ!XTf5[vMilȸЛnHSMy!7V9y˜mr;t[teW]Za`$&|r4r,BqZmn7lGRf>[UqB&{ۚt]rj$'7 Մ 44mݢD-Ջ6CRvj+G fB,x#Q%aZalZt ^H#EbˍA)4 έF B0dQ7!^xntf@tW`L(T'py8zk&WG2(BB4ںٗ r:չ[XqoƊ7X֊Ʃt-W[WUw^L*wd]v*Yg9#|JhL}v}DD^o\B+Y<*nI[ݲfȔ0Rۼx3-p;׸WKI (²={?6 :߲[*[Aŵ*sUScZCk."Raں3,*"1a<ŏ Eh{֡srs59$_>N֙}Ayîcظ 6(+s=0=٢uBҚ"{'y C̲v1o/E > ,vUQS* [F\>{ŸΥ (u4+V}hodKHwV!(ȣolK)a+Yc|z 8ct::V|<\nX\-֕lNOs/_ i Z^'sR8֚A{wNuVxc^Q Vmٱ*Jq@N-kKGeuoޅU;D]C^^*wLk2BYm٣\ۣ띤A"=˭G5(Y(HN轥JZ> a㸼 EmuU+ߑD)r3%qG]EE|/2aͲ9iZuWsoK0v\Ȯ]]z{_B [K{~|2IqJʤeK/@6PqmUUdZƹ !П^XƟ$7 ,ٷLT+CH!U6 4=d4d"ϡ:^ zKփ39Y$Q͍:lnSb(vmdï^NU!u0{zp=vS(OC'+ݰu"1. >=$ , )0`CQ2xYXZa fI;(j^!77΋o"w%T]ݗ:{;c0ȶ?#w2.ZuV NR7kpuOilJ+,[SЋ>.7.X^TN6UtB <}vtJ]Ș;>D#` .Јhj'W<)T oD㶅>.9Laf^z5x]r.4mNz`#pD`\Cfuh;9ÇKAQ3YD5?sܧw׹h>!%%>Zf7lP7Gxn p["ZtȺεTj.{iLW[9t~{=&W6ID k8E8ѩ}tS×$gr m[8}Q7f<5"e!{3uN9{ ?4Ba-^wl{}B30>:8mb V:P:Я #ǥR\׵gD>(m3fqlzUEQ{RTM ۆaTBv٢\{Ͳ^B@,:e{H3X|, y%ԑ' ݽw]+*Nj!;2dzxԾ03)+<0|ڻCXgV{"^q"꒖`qUu3%aߺSm1ҷ$cx >(,8΅VP昃퇷z.4S>2҃c@x2^7ڪd~7N}sF}ze9AYmbg7!^o%,J.9u(sTw2(*au>KEΜ"?fe ؉fuʱ 4}8uq˳V0rbD>ד$=1x\TR}=V 8@[ғ?agdxRiq # 81b]rW4X_p]m9 8"Fv*ħ"0(>T떶>6sdlˡuuM MOP|1e-><Ѕpr,,'ٝ5\B yuf!ȕ n/|1 sA$9սuP̫(]2q{d2ۣjSw2F$kmG,3tnqse{92v!V-8b`>[ BnӢ6YWo(2rxJ9-k)I4>Zw@Ԧ'MsʦnUU:o0tg:/@W' Cͨ8S~-֐4AO/h4Uyq9ҟ5փs?%K}Z.O]XnO6|~gû+XwyG)t#F ɽLְn}-9d4n,<e!ۋWh[gŽ BT~IKr C>Mژu)S'P0!?uu%ZVevGC$Sn fT`/hΦyבyr n_Du}[gC2⩡f=r뉣BX:!˰e*$wGއJ8}5ӹA^Ǿ8!vZAb1 )tڡ\iU~&őݨԥؙ]{Zm/||X! 6!N]Մ>n]g._ܫVG*__wj̭Cۙ[׳Ư0Rqڕ,/?e]P`CjKh0>=:D'd2:rzt>U[D%Ғ:q~÷;uDʰy)$;`RP;B;*4n,2ZmLUr|$1/T 9nd{dC !3 h zggr6;W K}n]diNڈ%ouVfai* H^SַW"\&ujqJ:V+vN&.QUeWQeš @ic3YwÊ O|>46t׮g"9D+Uc z㜢T[ymk2B>Ng1[WjXU}CNG@- Bϝ֯"^Մ>g[Z8Kv#8l( >G55eӡn^WlGHDt9Biܱ4ҋ;̯yO/xrŴ4cNy'Yyx3nz4 *[TthY,t96XdiQx4G,U^N\<4ђZgN5oyn\8d}/ <@z=(H,{K6k=DV/eKLX0ZEzM9FM6`!'v8 s<4@vY0N:'FSvk6ƚ Mߢ͚SAJ!Y)sǖ7`ޱF3.sֲQ9KbtY2-zPʪ7xPgai(lֆumZV\<7J0Ǵ9-YAuxZڡ fĹn[TV%0XIP^UZ.<lJ޻Ă>YH=DUfQdX(;fxrMxe.K铃Ʒn髳l/i #=ٚ|GuU;_Wfdᤝ扣gswrzv4)wۃlw~(98þ牛.|mR$hi=sm"p@\yTzRT>KfTj|>z|!Fk 6p֍l!T +ql#뾿PLu"襹w׬,Mf=Eb;U`41c+ǖ<BُHq[eH轔ϙFLs8L's%uEqݐiR _ucb2/]3{xvZ4Uu=5rӾz=oVD<|ffEw$^@ZU0WVOJ>0EV&bvO,9hmfӐNg4Pvc 뱆F>EVk7-FVR^JNx% %Q2`OX^1 82|(ْ`!hz4 ‰Ool! }ZGJ{9B-bӟcz;sڐ,;)se" :..,4!`?aDaTfL˲HT®NSۈrQ ύr)9,#sRrpeX! 4@auMFj `!ıZ7.HN)m6l/=wM5{:dlD/($fckcueWM.5B1@Ă^1 7bk0n708(6PQ[#Sm\pXF ZTfסF@ h6J-9`B:TDKX`b,3JiMއ9zv@i0Gגf*,>8֓w ]TO<&nU8>8X8I&an2Dp$ùTqDiy=ڼ4^ӽ}iohʼcF1[δ:Y=G[,jE27ow;h$*u=VCq<,Ǒ2tLy@TfwhY"f[`mU|sL!A *VW:qw:ΦLH] xa,`]K#Cax};y+8w8O%ل\W ; Zua z>$w0쫺h &AqwW9ˬ݂>[q ->*4{V8kX kVDCtqY\*K[I~꒲F RڤegBjG"[zL6{يL]VT\t"4R~2YT vDvޝSwc W3ت]pNlbw|aM8W,]r3$;Vm?OC< q>KwT#r+{/4X$3[}{<}&±ݩ|qAx0$8P0bgZvǢoW6;^;C%#w5@Q@xeKFÓ*3Ƃb@sS>géӡ禊~ 4P>SZjFXdY@i&Rj1 ;bS2 kE$x,[!9bMH) gy7eqƸsa#8}`|rVA84Q}XM^j:Pf-]}GNu&XpXnXJk=* C4HKAF]Cj5&cMi 0/#@)¸.$t.G].9 OMUY%Աui֯nj!ů58/TjIiv(D:UoUL ŝ],4hP5b3ϲv͸!!%E8S^/+bէݞ'lo+]5'Rj!nmԑ#oEB5t.WLrO%WgHVLR[i\ >Ш9a;wM$,r˗NI& C׮q=§:Mfə*Δ>`Y<{Xx0 nGQU`tƪXBAյ#n-Z{&]1;Ui,Lv38|'Mf]鰃CÐՐ-yh.ITe$ޔ PdKWsYG *5ĈejATq` A P)a o.@e!ֵǴE5Dl2U$'Zj2SV\*[֙TS^mޕ6DGsI7,Lw8 iLiJኃ&]zK*|h&k3]eov AР\F^Ö4;tqݼ:/C |YOHFZVZ^~&^;VYv{~@[l" ҭv*Jed{^ZjrdhCE1ŕ;!0'cg51, Gu?c6Tk,wצGA9cs}wADPlg!tB.D=Wbs d VD(>,(O]4oӭ<"? ќZdV&=KVZtL>OݬS[:Y sLmFD3+v,Rj]!bKn!P9|.fMjx>\=J$UK2G*EjmKܫB,W9mP9G.eYýwIGb*Xru,mfD7|;Fl~D+]q!jAi[یB#)kLCPKI>M 5V.Vb̗03uAb j FβE6uwF#H Yr盰ftbҒ[ CF`A{]J>>ۣꀞOgwXMW=0TN-ՔjIMlD8}*k[z%[t$X Ex&vz!2DuQҽ@y5 (g!i]h2Vws>yϰOETd38"ҷ>$$+XxF޻]1{g$s{s:+M3F:M`h7y'6:s W v*3@ؙutd~7(]qA0Z[,~즣&n})=Iy2w-}^.Ӿ\hKQiYڢvrlu(5u.lEokIx\ջe#P[ӳYD"*FĖygW!PդiT'fuo}4M筢eʉb8AD#Cs$vԭJc -ϻX yܵsܟڣH5uQ ei.XuJ`dkY4qMgP\:Cer #wu9~gFUz܃#OլJP⦼V^ъ:Y|ZEMтȽ(eRI`۰hH/Pl@RN굞r9s濲)G~|.9e!}ڄ<_-巇d0Cdh$8*֛+vw n mB:Z{/lrtg=K7[I>FYGx9:7r䎅u m[..It׻rT8ܳC!ʬB^L~KĆ|zS¬=WGgmky.+4.BP@HBo%SBzRдHfء0AW jܦ=hR=H[=w0ؚugPӴF9.Jj[oYzZdj'Ջڹ}Uaұ}!w,rb #wq{{l'/xիU"؃˦\h3~/T/ |6;~;/DJ?uL˶R%LN&Z" WŰuٽIXP_ ]Lo335(WoH]ǫ\~ƵLG!" 1DV`t蘟Uh) ,u {HB (Y x7Tj1nF.':|RO^g VfƐ=`iC) 롙S8XDmyY 4aư^=}M +Ob/y/8$FE(Ǥ4\]ݪ.;ۜF8.`= g:S| {cuerJ^+߉^pztL;x]䏤\r20ZգݽTB ŏoF2˳{oIh=MӫYLxiVOl (j\f,vRqJB(>5l]2 GU[.d[ݢo2NЭĮG).`S{ݛ;no.,ѝ8Y憧/BZqB / K3jYmTpw^Zs Y7*Tu9Dan˧O2v򽵭KrofDImAsԹQ4im]AYiʎ HC 7V7$)L  JvAUadD#5.seV>e0l쩇Ӛ8 KjʥX3 YUzy٣Ϛ7BxHq5 bW#D.v~\'^[[g̔%qkPFcR1kf woHW>װk۷czn5!%D/jTd;nӪdF Pt`t{kktf*ʈ$1k,X*r2ͱ,e*A6hQC/lXP|HX)`9C@EP2=|dlOe-6Qd{Tlq|;꠫滻;vu$Q+;>1<>r {Ƀ:;8J]YwWYYEqqWwn:κQ\QqTwTuQM-쇵Ofd ,i6bڻ8?w:t]gݝQ֕k^ڶ^|j5lil:*;λ*";;Y򲻢+*./iOjlϯQ+b|,tݕguٕG]6VmSjjjguV]GtWwDWEmn벻*"ҳʪ :(˷;.#.K2}*)9\7޼Z! 3%.Hnn@/>K<Zco4`GEٙ`ĥ̈UP dG r'0Y1lFDPpCc^ m9Z;H5bltDL UXFd{mݶηPݺ/>\`XPՉ؈JqQ]-|*Sysju|cQ6-fqkiyݎʰ|1ō#[T[ڦ K۳ns vP glvZ$o⾰稕}> :>u\DwqՖ.`. b]X&,tK!/m9e.Y\3ۂvEGeZD뼺}& m:sc+nR|:;:ݕH&P 'Zwn/l];yŒNuZCA$ՄDy q-u<7N:˃ok\(^qwkpvrzfYv排vwҷ$,άG[n.*!gZ;p:88닊bNkGq6ht#nVWaYI]n4j{hm]2;նɵVtpwZwF$Ws vl܏3쳨ZDYؤ;paV"+aq(%s* ymΝ֋ִ:K՜e["{[۫mvSyI*)FE-J.TEխJ8#[nub3 jw7(W^]m]tQ fՈ^]CٗAGVu/KYnNnwۮbun.ҭyvtqŝsz6讕w9wzGgv[H뢻i9J,Ygt]-y-m;K Wv]gERKڷ%I]772̛qeݰe[H涷uDdk)"fJfbqyՙt8y{".(+9WYntGaV9mYZMmn;v[n^F۳Su,eJݵ8nwdwv)lw]m8ڷ.˶PQ˧]$qvB<QEOl:g =:vav;9{IHqq\wSeu\$:jD=v-j H*xZhP IFܨR8;[t+ ,.{i {5kHj2ݜcj'HEwۻzcX+:dReZ{Mae;LEDT8!z3*̇=;1F+J6BHNйuff[I]Lk;gE%9g.. 'Uwunݔ{wtruëyeYtZnuhwӹjD|֒<˸g8ݝSig3Uۯ:J7KMӅJ;[d]E,Nn̬f{v屝M79lg#Եtr!f]elryٌNyrmչ[Vne$=k[1qtwLN]j;iͼ[WIYGGm m: M5:8b3*Λk9֦kۅ='Emʶ΄ K{sۉۺdpNY۱Dr;ˋa 63;:[볮˖"sVL=5mu/7wYW7Ieg[pO2G0[lqܶf"wGt',,vH{n` .{bʴ;$JHtEu4{v'uqIcq ӶPEBwGsw۔\Wnԝ펎n=#ܭtr"7m]I׶ivς:$Q[ uYmZkF[dQg]m)H;'Jq<-] PI>K$&(-)V0DuYͻv'ID]H:gQwQGV HNI&B$:g${`2:/LO5Evu8n֝'QݸCd'(Hs{[kQwVnekVۤ.|ݶΣVRO0qSYVYrUm!ul 8G(+˺ؼ%mi(;輬N2XUTfP"qp3ruw.w :ddd#I)0M/'iw՝lYgeeC;'$Q%ܯH/c)Q"эRILZ ær-.2r/mͻ(Z!9N)8''m:GzaQuC7:rsBx:/nmYS')㣹urOmvY$ ZK۲۴r^V9Yt]yۜkw2! ׶fqMˎ;Ei_24@db}Tp7fͳT9rpI'\WI!Qu9\%@W]vԭ)jMCReU-J%ZSJd'H]%p0VҚ!iVJV]QrM*&°X0YKQp:Uʫ hXLRb\C :NC$M(\St.I\B'Jd dȰSrp%:GTtWHe,(Ȳj )p\SU4*YJZGBB.%90Kp:)кDžz'*p1\ʜr.5K.NN)tI.ҬRj- Td(8TtDI8`rHꖒҘȲZM *`N8- 5SEt.RLD1-Ru, ]C8%M Ee.F0Z%hhZS"Eu+qNRuVpZFX,*W\\K)hZb 䜓]Ժ AX- YUY&rKS j-E2.\#89GTbZtMC"ıK,UVQS*Sb.r,UhY0FrIԬUVTb Wj&#Qdp]Ci- tURj5\'Ҝ1,*r%iM)8(NCĺ5FJԚȺUX.T%Ȱ5GJ+*CJU5+TеF8G(✓jL'qEt$\uG 2)i, Z*UIJEȵhXV%t%`j-QYFE')\&ZS$ҚԙN VİZuGGSu]R:KZSD-*ʫTu Q-IԮQҎ]TN:'! ҖTY I8N)ԝi u'$4Ed Ԛ#U4+Z%h1MJ1MR\'TtIt.ȵ&ȷX2L J0Z*QXBԙS ^K֪BEQH~?qJbW)W/$W(D#O檓ڭEqqtQQuwEwqT\wĐDu'wGRfk -mdȢ..;*GUTDBy螁΢'*yDU+QDODO#CDJ̈G'S.N16`6[U)M Ul0f[Q[mIڛB&6U[-m6&Fچհm-m `mFҶ! iKh[Q6+b h6͈l%Mh؍l[*6VʶmEl[FmFPlmU6j:8l6&Л b-lE[[+b6mU!m#h6mla6mFɱM%P~)JuU)ILG&J jP PVIc؁]B _ =7 @{Q@ "PHUR$ JUPpR  :@  Q@$R6Y)JٌY`#U(RLf  P'SUWYmGm}:)mOzi{:x9vbӬu cYNH@:qť{Фsbn@nXR\RE*G{ "c7v}^r3/HjB"JP h4Q"H?JjHJJRF"h4@zJoT4=F@M4 "dLH?DOSOCM4=MD ѓMS5ОCA 4ސSJ*Wl R??-F)VԾP}dƥSto!!V&"OnL(!l!x-.Y/[SL Z!f.~~qz-A^۽$͐{^,CN)W{/~{ddvTpLj/ O& *؝М%$]D5`Rݱ%n> զ82) !#2'J; 3P&IK?]WͲ"šzYϧ'i4\oUhm{l\h<}jtҍ1х1]e,'!6'RnFXyh`]+! \Q']Hٳg#֗~%݇1 LA=BMз̤R VRz4iw#VS5L+s2â4vGQ52ˣؖ춥/'YCoeեD#N7ɥh=;&[¢E<n2lD_Nj`G,/'@|n߫]xX#ɛfbqC`~z0DWGޣ+x,)zDd xۧad)Of.Z{.nX?/3{Ea(O]W I~pE1obCb%{jZf$B%"Fܸi 2*ѭWd1FHv4f#,$(3"h"fA'5 X0e2qX31RKDHbodiJ4Y#Q)HS$ iH3M`"ر32I4b, b*4ƌA$&l/2 Y d$D$XE2&FJD ,IH`"[sm#LK`ȊAGݣQ@!#|}yt9DTQ(]Ʉd tR7*bM!`LB$"ʁ'_Nf( 4DfI{D͌P$ˆB *IS"/a"i%U43%\f}K J 6 e}0F*7ޖD _dOoMkss}Hw_~fk`4EN+bP t<*C@zDO5;P +XODWC_,5ľkAbI ~:EEu/4c!{Z +Ȓ( 5|@6C%}~|D~q 0CRk&Di0YYHT&|$h}릌B,O.ɉ_rb0 zA {zV3hI"LLDBZi _!@baddId(aEI?HƈbfY4 E,"F#%3|B^pdu/3 RDa6̖)*@ M 1"F/r!H%0e$L֪ɠ2(bɀ&j(ąAdJIR\wr @D ƊB &wRS 4 F1 0\)p(]XBD"QJKO/_kʖn=0Q;2u|l%F0#:31h $Rͷ6DFbōb4U1L #6` I#dL 5$#I!AMF(أh!1$h$2 @Iy&! "6acAI2`3H@LdWwfc1$@` f# TIhDE֐121|&$Ph&Q ~ȣQ0h4 I3=]J#(E邊#Ao#F(S%1$T(S4 d#H2cD420$)AAE ,dJLQ4 (Q fC|i"6!!)JD 2@QHĉchN W٤F(""3HCL Bf2AHiHl2F I"aBhBFDFBdDJHQ& JWH`٨0%`#"H&S ɎvȊ('w@b)̠C_tM d̄l `I۲yE@$jR[TE܀L9Hħ6igzبGT-TX66 ޒ =kbV$ 7V$6cmVe&d _A_K{UPZ盵 + Mlîҗo>64K۟H<$M{xnȎwuMja fn4aM>y@'?2^>q $αAW<ާk&T'S.9b] mhxuC#V"D{"c=C3H=$(\(S`,92r<:~_D7e4\$ʣϒ;;[ײrÓW'۾1iI݊쐃4VKE=p% {~=*MTλW;GJGӈh;B4ؐ #G Eܨ@C //sHȊ=J<*W[x$𧫙SW ˢv}}^-^1aAQ02jO#>YhqDEcV+#IѨ[h#OTs$ccwRE"tUI;ߟxWM B#Έ8T#Z8#Kda4EZsH6k+B^"DkR&ե+l 8-F4…[6'9r7-oo}o}M^y6is(g'yoB-C}.}c I,`}ɋؾ"*;"dNSeZA+jrڸ![@ES$&FL1h@湥@OD*nhʞ}6cԏژ(cAdQGCzXLm{蒣Q<̷W}*"X#cY'=%qP}n5L:{Gl>v&8O6Bd +M-gzl&S-l Wnu@-(Xy g,FDST TkaᨲmdnfiFA6ҚN,g8Ѝ^zVEQ{wd5?Vwz'ukh@s1VQ-Ie 1ު 24ΌA0z_vSE[k|EU]FO8=56L4 &ՠ.ٲ@q*W>>,D0BM.;hV^,;}FLz-ce벘 yU>BETC%lM{KW[l =jBz:Ejѱ(D廹C]I6E^xX,H궥ZƓc{ϼ)=$Dry/QG{{£!Vƕs9޷]4(zގrZ9HxٳJSUpv.n-v026-6'ER9Qn L҈LTM][OZ\4̛^@ve_E/&$R#Acq]E$M&Gޕuت=_FvnG3Rf*睊'@fDWyN\<@zHEK䟐V˜&1#e ki }wy%_i"hHM&24"5hU.pGmJV֡6tB$`FtN7^3MrX.H>e4}}DB&k%^}q\mQ@56Z68 }RZ3mbYci0M\ hbeA F*=6nbTѭT+vK^]pJ8n옱 D'Ek6I1R`US~W;ݼ=WwĤvw1װg{*Y] WϷHkM~I'LCHnmBw | N9niD@% Eδ]ӝtX1H= OETIrkM&c>A\v.7(ߵ+ +L^u6ͭ( SMDIaFx~Y~i ?&_ũ-E#;ٿ^nTݸp <*{b=͗~mv67_KFGva_'sYOý&FA< i0гJG}I{;vC崢%&$| (K.>x`qA}Oy+C.Q=j.'ZڕG*58-yRMx ԆVk}hmEېYw]ZFe#D1\7\vcV7;@=VQ$X~4a![infy5g򏚨{}Is@KVr5\~V!@_Ƀv?jgO֊Gie,ЎC%?Q`м}^t/JGe,2-qurIݟ4'/ce}õ۴RKh,1hF/D?sb2=$ү؄H;K&םK~[Gzr;.mͰŬŽ5sOɾ>-=]6.tL*%٨dU>  t 5TGx5i3gNGF^tY5lM (٦֣}[it)Zpi ikMOD􅦙4~|Zb,=ELQ/Ef*"yyP8a ctwnRFQX^" :qʪVýhEL*U6^^Rg#Xt:k$mԪV!䗗'9^{[c.O{sWMur:j$0j%y66y =7Y!EyZۮ(AF{m7]#`x;O tG,e쨛[M-IEI#s1Jc%g ] V3cNRwѨFk{&@9/ ;(d'7+.XfuI/ 7X!I3uqsQڐ14/U_L"g db *30S8uޔi3l͐$8(kk٬=T9/-J!xKV  zզʦWc3u& àOD ^$2sEmDZp ꥩ)lܲB<L <ۣ- | j}$wj"CдB"kLDfIjqDش4kv{lg8_Dh9 AD1ź%Y*&zdRbA4S4fѩkC;ݖVxTmljA ZL FgȆ30={*uvs"5֫:g$'SglhRm>Cc;}KE,)6T2w_]`&{鮢3O"E<Ꜳo_֟#~6OJPd#M;=kIi7;s_ QNJ%xl.}89zeHbM:$A;8~!*!u[ ݻms:H`Cūw-zޟWMa HvfڇNPg/bRDAdLatMQ*zw4l{gaZe(,B2U9gBPcވ DND1s\ͻ4QOU#OK]r5OYaIgx`U3zof<4Q c3~av6tWv ?Fi~C5!ӂS1 1tTO 6 qrX8%K3[L0,ζW"n;;SUr$aMx@V(aܮԉ錽C)gt40HqCzyڣ.ɊEѯ0'8 X: {_w47ZL5Ծ͢[b(9i~߶,:k\ e$瓧Թ0DiiJHbAmDcD<I$ |wq9 {n;n;x["1+,vu_G7dJjt|Y#ŠN`_KOYVV5Oz21!Kf .!/%eͽLeϚ&g{y.rOn %]ׯxe#9LdAu_DVsϗ7@I`f ozz/+حJN3ЁƆ(C[=, bEޡ=1~_?!".DgMDD1aj,RgII{ɢ:ߒҁ?=_V7rgڍiĜb;y[_sHzݎ%2JkpQ3i.^ѢYlUur(Lzv;d"M8ws7ϛYIkJBi%yMǞ-/ÀF iIR+ D/3ryj`oikETǪf#w}QXFSi?|R4~uFp*#o`ۢH+?,I%ޡ E?ط;ݍ?R< ,=|ŵfY2J&_\o&D<=wOoa&1bW֡PѶƾicm+O &'/f)gOڇ&tҶ`4:<0J>KIfIr=Y:,&??<'u =An6qE5wq ~rPq؉1߹SKLfH)5]38×, 242 :dD}Jo 3ckz|Z곤nFȘ.`fM_1tԹ&H LqQ/Ou]Z0WS/q#Le90bK@ -/3=F.K'kGU] l]O;󲯿3LMSOאNczdemlUHabnwC~~.g}o ~$(cg';4cqT'|m3D"D"ɏ2 z_j(M}U1 8T NH&!cKzf2$[C~0*.*zyNWU.!DKet]ԱYsPJZvDQCS3M"EA@rSb EɏVE5z*Eʰz(U:ь9y!1 jh}oM؇btNF%&.mN)!LGVn^"0yђze F䰄QP;0d Mw7k 79 Q2VS2F)lYٜjLjG1u5ܻmEh0zZ c>mӝڱ0^4W]ø/14{4EB W Cg}F>_^{<"0 f-SrC7_ϓ-|f=5[=4;$ʈA.xdmRbs=eKƒ%̰ xEPb(v1,  Sjtf>UQ'MO π"gYAygXdCAfi!c Sį)vCn5:p쾡CW[YK_J;\$(^F&'TדN,;""1▾qT-**yA'N4/ v{.f})hȝ(F5܏_nuɏk?q:3j ?e,Vl2R)?޴;'@l̕ g@zwU'`:]DVLQeqq,n˖yĉyRR* k&04LgL't;UCIbJe[SO6'C4-~z3-KB4VZRw!>ٜطu maZh5E(*OR@\cG4}K S*/w7->[M4K \ZvLK8G[ =fE}ГF I!zr#W3ƷX>;G/,^Q6ڗ-ӿdekq\~?-Cx<&y.?xs;w!rz˚ռ޾Y|WȳUTx}ﶻ疙H_7@?mL2Y&aIHT3` 0MD$$Re`d"L4"01Q$J@ &4S hBECfA!#32R)A2C"4 HIa2Ȑ2" $F11aDMa)F4I$` HeQY,MJVad$Y4j4DDHh2L HQ$df1 2M%YD`II$bY 1Q"S,"eB2 b !EE )Z,a)2f$L`F3E؄#F(3AJeE HYK ,!Jj434D&B6f6#RhD"a4("I4iI$lF"(2)X,X" T `!" A$2AmŠք%jƵAElTlTTʹh"66+Rhձk*V6ŋ*$Mb؊,XmEFh֊b1E%Y65ō6Ml1IF4F6-lLh6ŨhX QcXmɶ[VdT(6),XhmFjcAhѢbDʈZQ@QiAUEcbẌXɵV-Fj""$Q%AcAVmQ%Qi1QhM V4QARZdTZ4cQ@[E`-EccbVQhѣ[4Z6,h+Aj* bѱF[m+b-F+ "Q6b0j,[Ab1Q (--mcF`*5I4[$QhmTkQEY6j hڋFDIɒU%FckFJ0Z#$Qj cɵQX؈B#I`T#j *KFhƱ*4hc$ѢQѨEF(Zb cbQ6f0T &DY1lPFlh5c0-5(؋RE-ѪJ؋j-cUEl&Z-5KQmE V#EX"-TThQkTmEblVVPh4ZmETF6+IhVhX61FZ1EDll[I`Fmd5Th5IQM!j4bj̶-4hLDUX5!EFcVڊRj6Ѵj4V-EVƍڣj֊Eɶ+`hQ6Eņk66MX QQl4jlQm(6i5XXU[%F6EhZ*h1QhXXѨƍhEb ԕ&-ZKъ**Qj5MEѨkQV*4[ZتcbjMf-F6EQQE&ňc%Ij Vhbj6FlcIQF65[%TIcXڍlj*6 JVm2ѐƃmFŢ+Eb b(mhAh*-F2QY(chc`hb4Z"EDXQPZFVPX,Pm-6Eb66Q`2$5FF-cF0XE20m&ڍmPj0QmEjRQXbD[bB5#`ZbƲh֠ōX"Th-664m%ATj- Ic-E6 h#i*-Ej( ̶Lb[j Fŀj XcTlhb6h[F(6بTh4hTTQkbEcR5-Fز`-bEƣbŋQQi5I" ZhV(ƱՍQEbi*ƥu|_Uo]m ͙6lI>u#qWСz%^I̞QV T'Bike/ėIvMNl6*V3P` j3B:jk_meײpK1bxУiC8aXغȘVtp*-i.ؖ:jZ):ăֿTU?RC 4̶گ[нG:ǨUI멊4DTJVeEi.)djDrަ$дU.ySCuWJHdt)UEKJWl)vKZ<0#=TG xS2`k&dK%kW{1)?쨺hΤ_!$IdTyeRI02FBjURR;)kUwGߦ23edZ A(/%+Cqum;jmls6\tva7ZκӶcjmKnIf[Z4?3_IM0g{LiCU_?;:?2u"_SoU6I]M) 7*/WȚ8;Qq'zYp Q~m6c7 zu/xw˝QDwظ.8yGzR!KG# ~)qdUWW@rFmT1AO]G؇¢^أ'N%D}2ܧJsrQYݓ)+I'tTw/d[6mTN>"=ͶMe[lkޯ|%OŚ_R.tTk_S2($,1&-L)|*$EƹCZYjX3~[nowc;:M\sRuݢeӛnxJz^ ձI5R,VllMI8/e[=ز1Ə\mWtKUTyY vx[/ރ503Guzw<mqb566G\7 t:mzzްAO@`7EC a4@Fh썱7ӣLiţMe퓨P9 uP_;){%)ΖqVĭ 6ZfW%ڇhzm((WrJg`*WBy`mNȳB_zs9{Կ{m6ْKHS) T>@>%vvBT)xI +:K'zchcj[U̗9W՗u޻cczcO=U/aTOi}.++g-"v˺k^Z&=N{Oy؇yuu'N w}hhqKS<(U|{rbWl%S__fiC"93A13VI CG)`bQk HۯD"O9&wS*/EHD'ͽvM7 @!=6 HJ1pH` bƀ״($EcXP" z@\PI>}]|[1 "{N}^0f{xaRȷXtFje$a<J{N;z$ыzORy'FL3ψ`so5|j$ 篼}v4os5m6o׻;Q @ h+^gbxf` 1]B߭]ʵ#Bw*H/7*~*m~ u#3F*-B j$Bʴ^1у(|_]J,)i({{uu ? 5|=*8zQ,Ks#Cœzj>rhVS$ʕEC~k5vLpݭd훆vtwgN!h#f/`#X7_Ï(s5#Zwonji$2k9Čy[FN[gF ڄRCm>ݨe\9\[z82Twժr+[0ȓdĔ̱߮Ӝ}hzJ_}D[Ai4RFm}wG^tJP+XCÄҔRI~nsmsnsb.ܣ{9Ovmr4I'G]zDKu]NӀCU>n$٤wWNt [Y]ݒ_l%YTv03O\P)H*SiUq^|Yaj]ղ⇹e'%ҮrC%p?r"L (5-uBzO{-44v{5^efu]< )UYk"/@Ɲ6me)-_0ZMCZPL:tM)0NqyrUS X'(]$XMNR$̫KSL-*+G\+BSHqsHP\M@K21nVH%OdS_U_)132ӷ3~'7wy;,R Lݙ4J]&ۡ&sD:!U,P)|]Jdq6eɂ(ԍ|_FyۻFLQJ4wŦ4[)̩%#JWf,46FA!F54.l'Ě*GJ|Ol͚fTwW9ld{ⶩiĺ=CU8оMmfmf#زjH9 Լ?d925; I.dsNk9˜=2rvN;*9ܥT,W4\L"Iw8Gڨ̾}uTbF|$֏Tʋ.[vZ[[q}]={73kxZJZIyFHF"nL..\zUTD8b1KO)65ImjQX֨mm[ FIE"6b(=jEG%u+֭wN"s7.ɈVy!!*NHS19[~-z2uC%UvmLXHcK+@ FޮD~tWpjG̸O=Z 2C5U}2OM7},|4扜zrPsWիybbFY1F) X(эRlЪvrIEcTQmԥcsW+owok#^FعW6Z罸R.Iʝ ]ΆJ5y GZm &R,wjFwkum lYs<xS6雦[asV-l/ˊPƆa;*wB(I'.{Mr6$Ƭbzn1${V#Z2JƒH) "5!mȲQ4Id\SMݓ=&{C!И]9KUصSW ٵìʫ .\F˨wuncNurpSRiR/YqAƥjfƇd_=G6IK U^#qPOR$H"KRH‰LW+D/4\r""L 4,].unLG,JVͲ#n{~I|>rni aM]Nr~JKFā%m[W|$w]fMlTm7LZ%666I43hVQiڲb^ZԚT, ҈Ϊs n0 K/d͍ilٵlI~_$E6ɵBUTmJ͓GPR66{/4Kh_HQ<޼<%xDI%ξ{޸{$8Ow9L5|ܮۓ.dHFɩ(F6EFK&wtI9vI];aJ˙ݒ^!th}F*4\$I<Ÿʼn}wWBLB~\CGY%Cc{;bЪhĊ ߂oc,ϯ\Ά&/|y&6aU K⟽yJsEݛ\Zq!+Oq HWwZW FLֹDMls[o*jbѭb 䓺8DiJpΩ¬_R_6fkl33+6ij/Jq_5;rth;P f+ѭ mr#RcֹKo:Wސa@Qm[XִF\Ţ|\Fj '+[(4@W.ZsW0[1h65z"mJ2Y* nQ5km^J96f4Z+U<Պc6|\Y64mnFMKȩRS@Bur/-FjrI&!5cUfܹ%ۻ\tE%E{;B@j2bьFQ\qf4%lT%m)II]:62Sns+nb;Y‹BWTίlIUG uHlA2R,F$/ߵjV/Y8*]6,` \\ĹDC!:yxA~:Ƭ6 |~%tMȶsߡo^*.1^ЃA3~"O_ᔬqh*'CܽA+}n*U[*ٻ^gŴrujWIe\.3<S_Oz  a 4lNa'ȓEI_"GHG:0xԸPlfKGLW& X r1>Q3j>?jCۙ;NDm}&yԉf,k^ī*"hud%V"a]v쓴n6fI 3 Y_U}Um^կq˭;8rᭅLWS$e t)ʒO2|h<>I0fD< y|V< \Zh3m-:=@=ZEYy!oy|D^CQ Z,oxfy^Cj1N]ī"O_wR*gV: ',W9ixw%O9\^{뗑5kΙEjT^]^FJxx*->4k[mMx]s?]R5J'r4%]*j769/>7_by_>-6ﯞ[}TQlj5jFbڱX+[Em֊jZ(TQcEm5FZ5EQ%F5mhciT[U6[JCFZVűF+cXMmlDmZضcZU"6#`6U66I!PVlKHCakc[!X.dF (I^y'Gܝ:x8Vf ѭ+}*d ';d2g vDŽ+;349.WBMYƯZm |jlk_Ncbyk̖jnFG=mq$5'p?4|> Rm34m666S'/RW}1x+CYȭUz_7RT̖ Ο#O NR^J#ʒ"b%B)wQCMZ*j#ή#Ad*RYT"gJVibE~;y2 n /oNPZUBq(|;89-\qUXi4$GGq9Dx'qzcF|;(I+x5k[#Mx"pg!!7O-d-X]QmFȦz+ܰkmLXUpjbop8D"&O>Jd~ <涛35\W*]㢽Tb.I/Du<ؽ*΃[iHLKj7jSJl^}MXUZڶ⾚/ W}:1[l5JT만G;I« 22CFD]DG@ ^$PJ*@>ڡفgH  0N: hPPrDBU"C UR=(=7,,T)(( PP)%-0J(TUDO TP*()DTUDTP*$E*OOv @U JA+͵wDgE A˷! &|0y=Klv^W{+(z;Ć ]˺(˸uQPga.m!ShӗZby*h4I@7RET tx͗tJpl-z*"%$4Di24`C FCFS#&A&RJIM24 =RRD4@ 5Qi=E?SOyShi4RTA4bi6S~L&3Q v(/J$\뙀GwbuZkC'uڂMriQ#ȔH&PIhk$3KHw۳D3*SDa4@"Zr!T4n@Pi.nn't;M˕:0-] BD3I2HU9$HF#"r($Ӫ+d'j!sYV*paBA@"*5IrQh7Z62 W"K]FjL(ET$-J*BIX n۝IfL\d(& T]UX u)]wunE ]ݓhLF8(ҹ$%]Tj3@WNnsh۹7et$+&$VgL"E H6D*ȶK.$q($r*&*#-MR RK+i4.EʜD%E!$a)DdUZpZ!DwW(p8uݎXݚErQҙHDWi̒9r P%au*\G(ܧrA20B(f Z-Ei%+"08)Q!ȊҺh\J!25+* Q& kEZHqM5NaqP3*ʢP+ M P; 8X,UdA9DdtR˖T##*KD#r1B"*#6l갻L2jbsKȪ NaAB  C8PQ'N,E k&Dr$ cF$s9YFavh If"EY]#k ir뢒E:&YEqIT*GRLHZ DS(HaA쉌\ȋTH*#,whn\hۓh $7$2t SN!$1;]\F(Q a$%1Ri,ɉ4,bɲD4I,hcP"(,bJHLIhђ52Liْ`E*( cA h b I MbHYCF1BR2ZHđ%4h&fi(1"I HJBH XL) b20ĈɌEa1bKDI4Zdi&F DR8i01G#QɎ'L3Yp$$H0!D4f#F3 " ʉ#!FH$MDљi%"hD61*HDHhFa&Q$`# X(SXHѢ@ňFdI&$QBL"2Ec$$6Q} 1 C[I09C ݝ{ X#:o?i~#ũL}p3SJtx4`Oާ]ᅲ=EQ` (Gr#1=G_ԼȹLoĨL #W~qym!eoeۿcE aǹo4 E5CWhA!-?Ȅt.(HŹ TגQvA"%#wš~6J ;z xbm16+(9rm֊HG4 Vǭ5Vy8j4;4Miᜒ1if #1‡>͉e茜3Na=pƜD (epȄF887aة8ml86H!{I8ytl7HGǨj9Lf:"-t Q wQSJDҖ8g{$11Z0:EBUhMo%Mg@$pH!-b b!A& RZ2k2JHE TlDlc&@4H 0,mcX &J@DIXbDɍ4PC(32(*2$"0!lh"BJdE)"lXc%)#Ȇ0i2DDDhI4QBbhDRi i$h1(!*64)QQȦP2#F,D@) D 0b*"&e4 dd#5$DeHL1&d# Ie$fBL&#"d# (B0R&QdЈeldDDADm$)fIbTEF4TQ,l`͘flI&Q i4$ -bD$h1(XH""mF a!%(feei1(cl2 ֐,J2d(ecM$ &M0Fl!&4E&h"k F1!&4mLF2d@1Lآ1I|pRbe #@dq& H"$D |SC>T)z|ƊcQ5cb6&H@ZQF؄L) T`1lZ(14Ti-AQƈ*1"m0lF* MP@M02M)l ,lF% -#-3I4XMɣRHحALѲi5RQFTb1IFALXM&J$ FD%aVSFɢ*LRmFƣh4cEchFI+"$T1IDP24$FIA1PQ3IIbMƊbX"QF"E4@lU%BbQBV$hPTZ~NQ(E`ѢbJM2A4cF1"4RbĚhX(؊"(ddĖF&FcRRdMMlm%%QDZMcl&Q@'t'XK YJIe; [- ED?_|+zƒz@=6S0IRzݱp 1bq [kL\Rq`FN{s9_xB yM"qRmŠ,Le7^0 eMaDAk`Hӑ u߫f+m$6*Ja~֚Ș 1`"$DΐV1Ωrg>_p<\Gm+ L[bTFMڊQ_M3\ ZZ`|2KKҐY~~ snQ.# r`FK+$n.Hf,p5_qkw 0hQۢ>(?4{@:7bumٝ.qh*#PR m\-HB ~հYVz 3-lno\?k]vf#=_q/rn4aSDj)ޚ6BC][MX$C7]>3Eb=Cnf.k3P8<[KZMieϔ)?#~~4/MuݒEZ^3{ht;^Zg~ w Mpn8 |"; >y*aV `iDEdeRr +óg " !‡ݨLG6-@לKP]tz%v\'%?[LayC #%:pX[`70Nz^tyF9#ZΆ`Zi^huH, BuyDEK$C`>r{߮=]-9$Ïr}xS`=Å s/寓^<ƽpII^yi8_wO'~78xQ+yK pJƔ@i E2 ФR5N,;{rP^~T ]|Ӽ.}ߗ2Q9B=NWzI=ߐO}|8[:dLH 8Heӏ՗;:߯Uwv(QresryПSUR_}>=;zyȗv y=g*9B i  8)$H?GJ{j{BMĹzM+o]\T_wvE:yy/9s$"c -UMGfpŠRrA,1Đ E!{wG>O'?=r)YϽw|C<<=(|kwiy*^|I_"$(9x{F%JD(`"2DEeɔ\̢rHC9Nqy$, $chѱ4EA&-Jdъ#FVfTK6"֍3b"6DJ+2jƶ*"TQcllm53%D(-lFMQY6mJ,i"*K$h c%I`l U[([%߇NP+QH;tE$ Hw{!$>Wӥ|?=裞4_' rzXw<]uGsw?!wz$I2O-()A<C7eAfQWϹyGZJ "AVע<8NhL6bT5%%EEmb@Thъ(JcEF6"6m6QjKZ,Z(ڌ*(bKjHZ5ъlRm %@%j1ETZڍ5FheXF5ZZƭڴdڠ dw֑ԕAE izc53M48dƴ6 N j"G)I!pNZB%q [ E -E4-OX%01l6D)dV*uBV(ْŒp* &Y34*n7Qb`Wh\pݝz Er7AAaPQVQG/~I<};;ER͐y/G}ͯI9yeǐXQuZM}_fst.7{D?}>.\\Ru9yQA}y37ϷyY: | *9-a""ke. l7xJMuhKH\4 ˘XL .C{ 뿼^}"c~;m.^4ܘ0[_xN5qlTZZ6y^}#%Ǖ r1B#RLX:4"Yk[=q+ϥdPE1l8%ԭ*Ywl/oOf&?4ҷMJ knw{z_y}M0+v[tAUڄ t@Qg\u$.E39+%#+,q_51q/QJgt܇T=VN1W{aK!QL2\I,'bۣ-dSyD}FA˻&gpHBA PN!铄=5ڎFݍkMmGg߈Q߰zXٹ!=suuUR┞vk77Li- wv歵tfO|?A%G#"]X]F)u6r f ”4e !Q֐UY0 ;]K $J%`xTJJ*EX|fNo^7M9?lSXew;şu]KDp=GpxgԟQ_=OossxUGq VkN))L{&)Y"L8pxwM(I20ϑ^Ayujr8B!ݡj5QH?c|~)!HaI]VDi.Y:{޼|{Vr"[,}t(FӉ(A :4i=_W !@5խ(.Ӷ(dblt lPY_z>ՓY+? 8Y 5NiѬjd[l0 |oh3ԍKrdb1&Ba]w,> E8i608UJ Q(I!ӏ11P zlii+04S/muqO/2j4+ƗXuwzlG0X!d;?wc"EHi",q}nޮʇft ywLJӇN/ִtŠ~8Fs\o ZcZm2 "aL]yb24c{wȔ^L3 ʺvv:>jvw:?Sܡ+;;n[CIϓUE:~,}ӱ޴ύ_k_P'r9~yKUdk`J?1NJo3D˝:!OQ^Dyw۞])Q2pHes ezI>U!'E.Sm@@@r`AZEAy :LdL:G*HPF=:|Zy FPǍ?d d{㣜}lhW=^%MMkEΏ:+ghzڭL|h|l\N: m r-5DIfIӸFaDZfY  /MSLDQJ*fO[q)+c.%GyRC1_\BV=4,FkYZ.ӭ9fo#6u>F|"7SHD|ej6xo:pOK2 &Q{j&ެJ\8x\A)_.(vQakMT2 5޽-h&tse-ſWN% U0#/u:SycVq1)\7U %+c,@ {UzN(S[6rƛa`(ޅq:merթMY$%8Г,td}Մ`J򂹘 Qx 7珞}oE>LiWaDg"ޱs_na~ 49y"ڜ@}R/eMN].aU(}і8H`\ƢXHR>iM6iLb0Vv njKX~Ķ-)wIz$xTtw_"pChGϞ|.7קTߪHQڄ) @FđcpM69"{,$D>6#eliRC-ȑ\*_8VQe0 #qjg9j(jq**UM0$š2z&{HX46-{jFrԎbuxSu{աíj-6U|kU>]7l]D\5v1"HFEEjz]; ~wbd>GL(p-CKI&SI e4{P?g+m{9dmfDJ3OPZ*}SZ*=45o>]`m1:up3KSߓNWž.}~\PpEVN=v+E$w6;##+| 47t_%,k E؃1#pM-A^U.+9aʭG/R]1X&`W͝rփK4+ro.FPSza?aǧ˨n[d=L;Nx{uE=imfwvDXhT;Gk k, Vq$AWBi'ޖ6 RL1j44ŎA pY}9U vw/TiW >VQ־da=9:b'f]X]XO+=7T08(OR$!ȶA_4ڟ"Ϧ"2d)pӹazD -RZf=DmLqݕ5A0zgSMǰOlwhOi:GwTᵎ=Q8Χ$u ZFNN6+ZaK [R'A=]F8ZG.VzMm؊[M۲צmBQ{uNDeK6) VM??#LCoav| ,]HԢ0ӟGs:[3`n\>Umoa\g}ڋ4k&кZ):ZqBY:'㖚3OkjX_*V~~Us.5tlѦ8L(OЄ.*n1V*桤t42@yZe}lz CbG±27P(Ij $gĹK ^Ci&mpWk|v<~Fr&w4!+Q.o<[Vv 6_1<q"}R$9<'5_\?'ù=sqD*k(7=/݊"0KEmb)D$2H~[5 Q|pTqwWP(X*umS\2&I$+;;?z~f$ao/:#4S pB_6rd_Ib2 hQ S2fE!?&PSճZk(%s Q<)DHX.pA7V2tAAU"gȲ@%MgIe8~̦." ;@8k~/̷ʞLv0"ۢ/^3R8 t^R`VzQkwGsk\- ;!uep~xSɬ\-ձ* Ϸ_nB;?-3Q2A( #.D7&ah! 湏\x_b7j5Zi/n^mΞsDfuMr{>M_z.ى_ !Ij(ImcО $VQ1w2{c]]^|0,UC{j!IkfE(;7\ɉMj aF<-ySLD%UgD*%TM: N.8z:dY=< 6Z!`$N"$") ˧_o2="9zǑeoП:pPpPK̞ԥӮ>EKMl%Pg13`~e2{.&%(Ǐ(,2!4@VOk&%BլPn zqxĀ_!PϕSx[3OsVc ZFH/_cxhښiYyg4hhpVK~HS3n--q*={ڴXInMD ǼMk,֜]W3Goi:IWy-t]\jb4T;O,`a-* uY5kzuK~ iBw#lڠhk-D™)albo +,po 2Vn޴T~1Qo"Ah>4`#J â>@rp?H3W}@ %a\H*-E(^*=Xyŝ1NuOasM1hj%Q5lu0ˊ~Ӈ_58A]NƗw9Q #;!jPb_X@Ji'Zp~Rg2X/[N/-@- JDIsiRO.5FK^@/ Xj:@q31na2eo|յ=;+Sfs_r{LwbA$n{y&=T4rcR/+7.ugD3zcX)q/ diCo"w@I'*YIQ?_,1|׻v׉ '=*~sG x8[Jg5ƟݔzD4!N}ŵ!>U -@Jk}MKiҖ@AٜJrYÑeX<%?ʇAKOD82%/pu"A 6_D NFIdLS) LIJQH84Z"H$p WCZXľe!hyo|ƮWb ; I67(=U:P~DS>%8:sNB 8P$~u}a@# FMaV?fk#ddԝ}7"u;vVQޥKH^ + &܇CV'2HjG;yH8D"?>C3k?^P}0{WL99m‰HIńܮR-"{K* ٠z0lqcHDDlۋyDMVQKbFxh=5*~*DT zK9{诜r\6:[Z>;~:A}5ͱBP5R17.E.!"+9hkyy+w#s7F` 33 >F L ?;ύDIQߖ ozV $@B|>P*0Wג&$  xMddVu^(WԐ}|8MN>N"9m奰Dy.f&P1lցB9vX"L t9w i`<3+$7K'Hj`/ێ~[i0wHB2MDM5rd!y# E B=?x''zX~(~OZX`P\LE;Cd%5G*FJډu÷P{d=8K:te]azFQh!a `qnȣ/>|=fV ɂM/#ew)s\bx0={gJZ,zGCMom#TMh"It-߸?y*V9#B<pmD0G`E6͢-:Su Ef,%{nC4_KNX%^D>$_4@AMy3%umM= 50Gk $ re"޲O1;)'v숁FJNNS.Hoƾ6ԞOH*JӒED0_/ʧ #tx>_E ё,-0mOG-9aWXzud<ɐ.JA0]_ %fл %ˍd5(ڄ[a=_>D,7_sf8Nh{w RzKBKꈁF]`_B> ȑ)D t2fcLOvUɕ{ʄ$?mBʒdv0 D2_ q)Pi/"2o'tZl@_3p|;ykA MQVxv貐Im[bCY =HV'8|`qD }s*a:twmlC kk:2z[3|#"Xs/ݢ>xF!f|G"J;H|p;if0̍ɋ]Tou7m{f˸s';=kyQFxC!vHtѣJdMdҞބELoqu"2@it F0OԢ0y3vz+WjlTh)$h}S ih۲4W%@|6qv DӃtF3-h'1t48K^{Yp#{r2-?R~x@@yoQa1ꎍ-ZD9Z{JG $C8^FwA&)fF A㓅RM6~!M~DLFB&mpH 鈝ތ(b% e; A͖#%AiQa~8$[<-B~b!`pQtB8̜0:x0ety9 cCUзTfː[,l̺l, Dz|w~ &>bHLCbey9ty 3!飥m)t́E.TaAOIRu"PKzXU$":x>GqU)9AK !=pv1kXnȆ2P8q-Ktm:gNrWeA, pg({Ae-&)d|uJ0尲62=]$tvʒȍw+AbqLJcHZPnЊ-CHcTQu*dcCD(`Y ߦaضqOZP)}~}}[j֭0M`ch1`љL d( "`"J,I2 BQB2F%Y,Bc"RQ",D2L` lJ4D BT(D1B,dI&2D&РE)3!"&*I(2 IFI!Hh D&&JL$H!) # Qe4B3Jc IK$! e!,%24`4,#"A2X1 MQF$!Pc&L1)B#&dđD#`bL,BD1L DBF(2(d BQ JCK@@ LL @52M&LK%2Rc& #dQ&X HQB"Fibd(cIbHȁI3K1!a1I)BB%c$Љ(PTK4Dd1 HH@I1C#$)-hFI!LH")$HQ"$ $Q%I (Ha 6R3b"0h1((D̉M`IL$dXB2LXH02#("! dFE1,dIH5a,!"&QlM% `(4"H2E(Fh҉ iLcF0$ȅ2a&E"E! i"LB)bi AAA$B&XȈIL( &JIM &F@$J@0"Ihi(JJ2,IfB(m )4L&Q 2 4e&$d&BS,,B&$"a"1)(TfI`3 %H2"F$ "JD#(l #!&@F A%i$0dLI1c& b((B$D$h2 LH&L0`H(II%@f2HE22 H)1 aPcL)0Ac3$I0$ 3(fDRL0&d *0d0i20B%4( 4Dm&@(" 2 XĉHlD4%(LDDEFSB"ZSXD%%1" EQLHhPa(%#I"#h!$c# "Bɉ D) F)&E$ d &‘(I$؊4& 3i!$2 f!1 `Dd b$!Ję2 &E%)bL1HBm&%2HF@EK&B0LP41bH$4Ji $2 dI3"d!PSJD  1Afe4!! $Hf h$d0P4a2dF%1l!Bd#C LI HME"iFL0 "HE"APdS 2 $D$2P(1 IH`0 ,f`d,LP"d$mI!2&D EBDiL"dRa3$Ll0LC@B$JEDI2fP02&`DiH`Fb"FFH&Jf$4#E!#! Dh 6I@H&L LCQȄ̘(,ALH4  6L0 2aRLH@LM6ibƒE #$%"fID 3(M$A121FcDH"f "3 f FQ0I"l&`(")42BRa4Xi241iHDB I"b2cEMQ%("" "c!3BHҠb FZPF)b"h#0bR hIfF HfHh12I+db5dZ6VCb1m&&"eD34X‰P͊$FHh0ŢF4d D"QE# 0Q 2ɄHbID2E1db!0 $RJ&%H $3`̘))1DQHl 3bƍ5S6l4DQa-1LQR4)QbD6"Q((5@b-A2T &1$" $da,D1(ш @EEJQ QhLI@B)3L4Q2fh4,dBLQT%!b#,HȄdX RXI"FC(#,Ib3EF,& R)B$$1LIRRY4E,P $l IZE"-bbIKiJbF)#QM,4lR%hb( !Jb ĖBFhM&2X1HJ( %! I RRdR,HTL I  LHBPR*0 RCJXJf(`2B3LF3$h,#&R(i LMɒ H#%)# D1idH1f)B1bQ(dh@Q$$BZ%DfcF")bFLB4&C! ) DE &dF("A$0f %#,0@1&LMC)BJ0HH4H!i$L$4`D#L&f&1Ai ` 0(EbLXaR0EL !d2cX1d ( LBm!F"("$21Q"bdD*f#FlX%lFF(c6R,TR&dlƃQM#F&DH$4)HI(X2AcIM ),ch4R0d+3 LД1b BRQ0M53I$12bY40d2lF4QFe X5!`H4HHe4RXD0"dTI1%$ddZb6)E!Xƒ d$ bJbđ%Ж6,ca1(4bB dQDjfhiC)l@&Ph0lA)CBlb 3&4&`d(DͰD Z Y@  (cI0Q% LII!!HQ,`MaCf1"e0iIiEE(0SI1&1FI 2SJS6ňF*# -"QABBAH6BIV*(&d  4A B+)%LB,&dXBE0"I4[i4IE 4Ȑid@HD`DHF-$EBd̠0cR31#!Bbbf!J5 %)1LQcDXҁ 4RJ*4FM m1 jJ $EbA %Lh )0Abd DDF$1(LjJɊQ`1LFA1Lbc41K$(H3HcL1Dh0bA4Tb5%1!E X12kIY2LL&" i(E&؍EEf)0l%d2!J1& 2ѡ,Lh!0AI &$Q5$@`S6*( IHc$)2e6"F LR%&HF!$Y,%"M2# ȠfF*6,`"*AIffJhi1BAوb"(dEQLf̉0c1Dd 3(l 2%221HYBLI4#6ɲ`0bJ-$B c$Ld fMLV)$Qi6K%)$VbRiCQb,a6DƐbEDh C LJ (Kcd2BFhэ D LH4h(Єhьc"&dH1%C0ZS fI2% cPEHJb"6d`&dBHƄ24E @lRi ͊0c #cFBdQ$LHFBR""hȔLa "R#HfI6fdhIP %%`bLlD2ԒlD%)р)ѢBH$R؍͌FLTH d ƍ i"`BI0lfc % "ҖCI%Z E4M6Dԑ&kdQ4d#cHAAd)6(ElXcQHdJFL,hFQC &"B) 5lIElHJh4c(Ѭf&4FRREQ$,Tid Ɓ"L`$Q$EPA&D*(E$R4XR)%SdEbŴIXTj*-ZV-Y1X*1ڋF*ֱb&[j(صljFI6Ql5m6բ-DZŴVQFѫQA*PcdŨ-cEF[FMXAb ccFص+cm5EQF-Z(ڣhj*ƴdQl Z"Z#lc[QTkbFڢ*EFѱbj6VeSj%hlcVQ[bִҍDQPQa!#b"(4ёb4fZf26-cdQ !bRؤ$XĒ`b1I @I6$IcdRbkű Di)*$hآj4Ec0b(M3A!(% $Ŋ*0Ĕ hi 0%HDDjlS4%EґDdJXTQD"d!S,j4Q4` b4I1E) $dh-P4"Rc,I,aKLdъ@I0A`Z#DF2F(M$P2h#dE&RF`)`T)dm`6())!( F46 PiQ(H55)!!" *a`LjdS &Q36i1*,&(! 1h#A2lR ͒6( S dd&bLEId#&4$l `Bh1`S!V$Cd2 KAbD &fQME %4P@a22JRQH Y$lJF,! (6X)12,RBX3̒@,)$mF!I@,`@)c$$b0S$PlQTS"MF!d!F(bI3E" $dh,2lD 4HXԆ40@”!f$RAbfi0ȢIQbTDňTX$1&LdFą)AI&"Hɢ02(6"L1 l›Fh,$&Q @i$,J#bf( 1ْiL# Dd" R4X Bd@Q 1I2(B% У$ T% 3AEH dAKI0(Łc%%I0X#&&X 0j"ɍ1@b") Y1`! "dddj,Y54YHbѣX١XM$Y),l)$fF%رR*C5iJ1%c,؊( #` 1dMI 1Z-A2 `ЈILJ,H%2h$DdD)c21eIMA$`1QFƆfRTђ &,(6"lD"0D$X(,bD1MH!hĆ 4$k0 2P@Z bƢəd" %JB%F2QAѴAh&,dHl4Cdɡ5!h"5`œ$2R (%LfXɲPILe *dIDTC&$%&`)! H@L6(6eIhbB#6K,J))M,&#c)E dYHX4(b"&L( $PjaBb,$"Bb,$D(2 i)eP4!f2i$1`((!dшʒRIDAF$TL& )h)BL $FJd$LiJ4m4Fȟd!@ 0MlM1P" ,A6MFiM Rcd  &`hPD@2fF bfhL@*LH DR@щDc$AA1 %$,͢$ɌHY($%H $,aIH#ʼnJcġIAc&$! !3! 3E%3KIi,h%"(Xb@hF DheIi5"CLQ$lcA+llE4TS"C"4Qb"Z FbآX"Ɛ2lkF TF!1h0F j(XF 4Q`i!0,`4AQ hhF1X!d)E$&!JRHhH$2$P24b%QX%1F e$2%bKbPJb $dRaB!cC3 "ɈHQ%(bDPBl̀&1A4d*c f)I@i$ф LFđI4A$b(JJ( ,I) Z ""d2(YA3RF4Y0RRl 4%)00(L Xԥf3Q)fBF1hd 3LHe(BXQHA%FH%041 ɁJfT#(̳M3 $R4(dD0BHK&d`ĘdI2@IR1,bD!cdI!B E4C !ARR B2!ʂai!(L$DPL)$! 0c 4&R$(̢5)$6- ,ؔ"DD4 F MX(LD1P4A# RIa,4b2`ƌ$L)hCA$D "KbI(B"hŌ&4TL Ƃ-&!DDL (ɈM-FHJ(D3(&(dc2D2Œ2lA3 )4( 2XdhH(1" M$$"bb(R&$ $F AA%BPFD "( 4DS 3iR`hɂiHTYhPHɉ(TP@Y4%&eF (ȤdLLŢi`d& &"HQALh!LCǏ B bQ2#I3H I"H DHj03 L*Jaa) ( !LK&4JB" h CI!@JFKI‘b)* %DbHL"I$͑ID3FJ$P)&3*0TF4d(Ѣ*4BdQF3c0Y2hfJ"fm42BL&ȔF PbC!0Q#`$ !T234(K ,Y!d(fbd Qd$ST&$Lђjl4 $,CeLL a36K&QHSƣ"5TXH$ɤ 1HaPi#2D&Id4 4Fƨ-ECJ6 #&ƍ  l!*(%j V1hMj(5-ƠԒXH3!-EQC##XdM,F0 !1DRlh(D5DQ4( fh I1TT`61d*R"IM#ki *6ȑ4Qi!4h"4hJ,Z `#*" 1%MA0k)a 2D4`A!JMlc`IILAd!Y "Zc$Kb RRV1V##j,Fh(1ƍQرMETZЅcV+IAA`h6&6ѴH@X1[6(Ւ[ضѣXEƱmQb"Z(DUA‹FьXňجZ-F"ɵĚ6hY0c "UdF2j)"$cc QF&2h6KADhE2hC@&HFF+M6%bƣj+EhڋhZDQEcbI +EmFQQTkZ" 6QlZKd`-bjKbѵjj6jDQĔQV5hZbM,j5c5XF5lh5LƓdDA +%&1(` DAj5bV*1EjJTbƊUKh*4`‹m(Ԗ*4 ,QE"X4m,L,-%FjeV"(`1QbԘb+(64R[ljbcEA(5bkV-F-h5bѦk+bبF6mbF)Tmj XUQ)+#dF"("6l[EFX EEbґQ֍Edb-24Z1 ETT1QT$X61űRhjBi1AVLI3lmbэ&Ơ" [XQ5LѣPlVQEQ( bՈZ%ETU[X,[Z"MQj#QMlkfEXڍI1Rhѱ"Qj6BjM&Fh5`b RXѨ2FV+&LcQQE-Ōj5Ѫ)-*6ѱֈ*F1IZ+E4PbFJ ڍdkF2mڍ QkF4TmŃRjk4V(MQj5FQbXQMEIQQFm`[F(Zcdl1mAbm %E`m,lZAX+E#Z1QlbѨ6 5EH3"aLe4#j!Dhԓ" "!2 (&ELІQb"ض5FDX*+kH(EQlZfMF+b-Fch6ŰTj,l4l[ت6bE6XMcb"Xض-Dm5l,b-4X4&(صb1l`,V+#E`+FƍLQmlTd*Mh5chjđ4 0dY "$R EJbcXM2"LQHFLh,P4a-AD&#$ , $b($dF %%A&kh(66ƲV,cj+ F,Ql­#X[AkImj(#Z5F5bƲmQ@2jbэ$i146ŲTRb6Zƍ#&űmlcXՊ-ţcűF1(1%! 4HP͈ɄذH(6bV5Xm56,mDZ bb4j6,04d1bKhUcQI)))",m,cV61S#$&$+ ,(ĒXJ VQe$#TmI"R;UQA`p|sG#+1/{!UYz\UWۦif<h;GznbiE'0$ OͲMXe)X6o}cD(UbʯQ-:\Jy)ͨ#~s2b5W* (<봝DqU66V(BD*U&%Z(MV6Ƙ2RFbE%Qm5%IhڬZbXlإf;E<)ГԺf6m +W- KZllO{yׯfٵmpTڍjl:އ!vښikz^rM3LMZ̒!p?sܣ R.NUrUԭvkߑ6%i0\jKΑ4#SM6mi[&msA'2w޼bw/@A+p+Ot9-j(Ũa+ QP(*2U'x]x6O޿8NrX+=!nfè[x闝<8{oFiZ ' N\I@?XHxP{-FZ)]yM lnIwlZ[S1+U6$hB$ʒkEʊ4>Q$@J&39aqj"ewJ RD:5Ϟ.y|͹ rHwR̲A*Ї;VCst?pU8g"PwK$P|rA:wyzpO''VD]It;,"<=O'"SӕlB4B';w?7YEFl1+$[2Gtw=iz;r'v{޼GJ!Sm`Q!(JD Vu^farCWR懮{"WfvQpa!.,Ȭ;Wgur:nSiKߘG?#CQoy Vw Nr*4f.v);[u<{AHqn %Jr%YǓ{x^y$9Nto!'֝!'rpwS$%NPۣzA'=득i ϜQtI* Jy'qF-j畾[~|kWt REO?F`ؕJ7~ FJޫ_qV/GDW:?z!9Q:44]rG`^44XF6":'x(+4D^p_m9u#G2N&_*KK0Yw/ K8U8adYE[!.T]j* t+N(9EW GI\ Թ ͉KU;'8JSŒ)XRfg(1")6ZGUҜ(\IN)+z6 hNZ%« :%h&arGZ)b]ʩX ̶#R )2F)LKC]38Ź\~O[Ƞxyc'~O/sri EX03I9QHG!$ ւ.)%`X8C*r*Ht$ $1fi տ(|Q!@L݌qI :G$B5i0$CV*-o8'SpBwTJ'usP>(j R҉>nk7+__M}oK}ر K/vPWɿ>?uwDL(t#v]T[VM]NI"Fx~O{v#}^Kv BUX%L7*/¢q/eORDR}S§Իz'9U{}x'W>lL#4VW1Aʮd-˕~ǸHr$1QJWm8")3QV%rÚ2" TҐ/<+UƱ*ckW6ZۆT\h21[+iɪ^'/˕ 0=/JaW-WWWH+U O_s"{Pz7Y[\n6ƙU `8@>z]|HDG tU؏H>d/ht}{GNBCU}RUpNF1r95E]qlVUZ-,dd#Zeڭ{epTq}uIq)txUV>@V+Uď,mQ>1/QvojDH.r ,Xq^/U;TC;i0Ͻk{Rkyt$`W51.[.}V;/­ȕ*#ƪ&쪯Wq*-U+>GW2_)$UX$n@M8.Œ;$2fW:Aj9^)uS lUm™blSaΧjU.)qmVjLp_ý?CR+ʧHr9A&-r<m,oeIEё,t ywIqCRhZ6pUWdPN0Ua}ʩK֛O\*Z%e^tʮ^]2G #'."'#xEWK4=%I҇FGzkguIQwufRTX$EB3+#(cfJ1l5Ibōm2l26L"c@3,bLdFm6m|)uE;ITsuˢ%qϧEc ` (Î[_Gsף>{=2E$o=pLW98qg-6/= ۨ^]ݏGHS=oO> i=ODN'|Z`0"H0o] j- YxIgw e-MI>U:ARѕ #e4XN(8w<~=V=Z#Ba!f٣M%p8-$r`$^ENkfzIu OCM8,}08:FN|.kDA8Q{ؠ`#}E vH8XAݡTU~ܶ#dm iM=$YI t=;(=u^mzC^mTsٝ%s+': p.^LH83ӇZX ӇԀ1.G"`ηWuH;s٤-V}"O@BAcƄlI 慀0ΟDR:p$ +P]vI c jD]OTI=6"N1/wy@t:RA=2Sp@C]I;f{,#C8 @xs]7TNZU<~}h%>]=>]3[6͛3ֶє@/G[=z:'&"dYe"RpDoP)rH&Hd*pxʼ{;c ת.8 ӱ3!Ձ-XdحE0W1fc$h(̆djmWK/z>&HO~ˍ-9sySB]EU <׮ S  lP8S Wy.(%[8n8isZ2&0d*DݲAE)D6-3Xe35%eX2Q`˖DLh#E#&j(#D2,A@cE3RF0&fI؉#lDMQ4аb F*lT6I" h 61$ضZV"T)64 $R &4$[`ѣRA DdmAE# 5cEbDQ6#lZJ5cFiI Xɴ6 4M$E3P$DPcE( Id" &6%@ɐ40H$ %e( E &dbdC A&2iB!B ,E3(DIDi`I&JaQFdLb#E+I $cTjM` R3@#4,Ra&E,"(0%#dY$L2QΐB1cF jJ @jbNۻB* -QLThQ 1رMclFRh#EdJ2M$SrAHcAQ(dhk)<+^`vA'|У(0*~!t*x߳mFI14GꟺI+|-c[5kF٭f1Ρ"wqZ/RJм+#=U'*BVk0+[-"')U\ii^~pt}G&gI&S  &$ 'E#9xN<><w/׏3_|_!}|>OqswBb]SQҦVU'2TS-FQ*j(y./BzJh(DT͌fdaL)`K P`"IIII$̩WbT2<7c=;*R_ryQ}㫻=/v9k~"" lưٴ5GGNT?e<}xki>w; Y$E>W89w 5r>/?Hަ)L)i|{{ym*lyWpNQy%qhvP9,ta'S訾:Rd}U\K&ʫ¹zB T:9CSyg҇l16W嬣J>\A=:AGL5K֤iwGLWW^W''Omzd]ivH*m+.74F$-U:[v^s7o0| |{!J/O)__abS %F! F"&Rd-(iSad))$ "($&ljMMM2QPbH` J*,bJHFT@Q#hɤ 2 lP& * E"Ab$A*,̓!3FłDQbAA+mI%#($ALɈiFl02d dFI 4҄ H )DM& d!@ш0Hf(! "̚V2FDEfl,*JLBQ&Ekol2)z$b_m|lN]`zx{36.ƍ$rrB*IIҔxb@km[f4c6mf2݄$qOPx#L9Gz|Cn5l-+D颤]ٳiW+sbJ-u*ImIV6W5IljMMlju˔ p -qB*LRT t 9GZJԜ z֭%{[FuR#̑iyRtd,ŰEQVb5j5Xح mJ9'}eߣsW&nM Pw"ܓtrwMLh.\ n6hٶ-Ar8 N; [csζ˔Qm&1S$]W`61ܹQIlsi&Xڋ6)e˔0% FPkfb"(()qVN#8yK^UR`f(w\""n⥶$lb޵vJ RHrNU SSCΫ/I]Dul٭b&4h GmQ_ u^߭el=t.YA-Ug [fl|w,Y}'RM87&[/k[%yd6$Ic^C)!%JmSk&6/՗$>M1< Y|*e8{s{&^Bw+*o8]TBv {A'76zGy7'ϐC>uv<;vʥEͨes2#ʺЃAQWUqLY;W-tܫW7&><ޛE˔MH"sp!^Nnre'o}}yۛ#ۇ;Har" ðFRaqT+ahiW"cdR+v*-U98PN9G<;aͳFYaLj 3@mpG5]{*TNڨUiVSK/⢻&#EtF[dQMdԺA8tFMٗ Nk_ε&0 #EH$F`):Iu*RM:i )ˁv:HvJ5"4M̋ X4+j-oU"E;k1mE#45$IP6ElTF(mXŲhZ+h(X4QF֊kk^6bcHh\*Nsm%tDEZ76,g49rBҹ4JH&r9*VR$:40B}m~CI-IMdkSt!Zȸrvxc#عr@|؉siԪSաl.`3K/)9h;@&M O  `DpCm'^Ipwr~Q`}tSbb.%k*®5M'K7|K%HWK*%^U4x>:UڠENwqEO%[S$%I{,˽RǠ"oUkݶߍW>ǍI Wu' u($K>w$J 6YhG/ZOPb."$!!!wU/WtʹFA ˾w $vDr^Wd2XI 8,C"H;;** 깒t)!ÞBQAy漠6L+,eVBL6TlDjFk/]o;iC,2 922u|t\/4\E%(ѾuġIhk~]ZNp-̧ԜvT}uri}$?e<vC' Alv=s U$RYѣ)P&گ+,[5"E][[36 k*-4h#i-#ƽ_杵fmq\~4?2y^+̏I=>4P7%[P/fWp^9y䚯܂RE~?l9]?>م#BG H~R$I  `̓" 35 dM` 13dKDјJH"Q5611dE1f$`#$E $HАo:1D32)ݮASd$d(F10h؈٘ddF146N\( J(5Dh!&6b1,e"&&\Rb65 QF&*52Pƈ̲b60 ƈPfinPHTlmłf A PZ4 dht#DIFIF1hcC,3IC(#i(Ȋ!˦RM!c% &@bDm j6kBEbIP:KR:DQ\ܹ].ĢZѧuBv.]W&ᮗitӉVT PȊZEaDg1&Hh&$]rssfԉL$6Vl"6m:hS FHH9):s8t1p";;َw]dRD$ &IM%FBR!("AFIMFLD[TPLC0DAơPLوF $iaDHCBS" XcPLa R&2A$@DBĠYDRf(De$!QL !%&'w2 4 LIFD,Hlc,RI4( 1D`)&dMd0bhihFLҐFL|dIb1HFo_`!  o`a)fW]\a4haJd$,JLPBV|iq.6VäFC 7/=St=+l)F輒W(jmsF~R誾}cK{s5Ll̬Yn2wqnElXV݈JM&{u5y&/6^Л"Lє631*6j0P4hE„tunN;sndær,&w]S&K.^q!xLN}G!Տ2)%0RkSݷF )ϧ$(}vwpz.xc8l#Am4^((|=b}ȯi|2X|'{p0mo6$>]8}G2&RD]tCRS6JF5!0RCQ [%,E1dPFNy;@8*JQ~z>_bܮx^ԼQd/(&I-Sʟ#GF M[EP؎_6P&%&)3A&m;QD.EB󗒗GH\qM߈ Oh!}QOee/RUV2"$WҪ+ŽtL+ڌJd:K+T:O]WU܇U1U;Q1,Ho*‡9W)ˍlf( Զ.19AvzHrFT>`)}='<8BbJ%VF8qB>~zs92LL䂴* N JqU*+qhجld[TH[:^"#4N޾a -=ѣDGd`_ )a\۷LկZ<#qṪ?5@Kc- lIA4g1s(rodKkօR 8.:: E񉴧4aV֕P56p 4r9X|S8adP( &L)؄.]\@M41qPȖ.s@d- ,Z9 5yL i91hX@AK!XaD0% t&Qh^hk +Pc o!9ܣg,7a}zǞr{٢GeGzm͛6F IIb$Q&(6Ѭ<$zq^\YoҍQR"S$.팸Rfh^qwkHw/ltü縏t^ YaUr!55bwUQ:'r9q{HJK+湮UyQWךm.h ^C-pyP>Af9 Àz$ {prN|׶7`cM !WN(YXtRj@'ӌ{=\iym+ʋJ/ZzOvUFZ#bڌmFjf@#^FBQ/@~J=nٰ,gC#ʊ?S#xH%Oi?$$_Rs_)Qm&9<.ߦ gh , 1-62!)Dp02<:$߯n־+l?к&mqUO܁eNtrn5;Ȃw>-嚌T(׼g71bꫮ-)ƤdOP6UdXpԽ Z+ul}t@m2FilPFgj@D_99>*KNRp pl6uI#vQ @ N&MQѲK/hجԤaE4e{o,$euW`I nL-Bc>º d.ZDqޟJݯ^^ۓszS9,Hv2Hg!r0""mt6h"-حBjS5';{*Z/{9G'3ϾrtDa*x~myi6%<&9>' n\hQچ2^6U vNJ^s)HL# )7&-݃6F14k!J5$ڂS(Ft;YweJ7{[j hZM_ ?&CZX6wx[%rht~YDdiLXi8 .t*߬Kυerg;ܣ^qn#S-.Ry,kj63i(Cm]}q#\6^X$#3 tĤNg)?^[0BZ8sTCڦG}5Kָ%;zз{a8:aMfB3Æ/S&[Zn_+,w1ju"pӷ+3tL_7"8;=ftUj=.ʸZ.'jZr}7vdT\ ]:)l8*oRT_f~S)a>)¶zyT.[E76)VsnJDDEJ mXl}@YW}S54<2r\O;yT25ZЉ1IX3Bɩ1F@,pvmN]#l5 ɾkXeyvɆ{ xu TYEE;d#j-Qd9S_ $(I$$BH#.0Xc+,![/2KFXr6gaD!+=bBy{kOwKL hl%^ R"f!Myמ]t6:.2$&_L@2~葂g cלЁ${D_vwa;w?ߎԄ Ao>)}s~yQ#I';i/Rxv;? Y}t/ۿml `IK>$d&O~yp~nrGÝV~8 '3>e=}|fwyXXu,{nN<v~tלxh=Md&l~ۦF37[t;[yw[_#{.R0 &_W 3l')`tbzN&F~>񞚓kꔄm(RWl4;glE'M ߝw) Oh8unI2XO1Cĥw68vVTiihE ;Ά"$$q.go!3c1d!5۔e& $@%,QV6\ϋB>gvJϵ7s[-) nXvۘj"3c!hC!#]rɼ0R MeEn\Zc0G9e0v)M^A;D$IDF4&5r02(Y̩Ya)ey?Yk&memY<8%$`a<:604i[;k_lC)3Ah:):氁CyU嬐! 3$SP RJ` n&H'qŋk57fhMUD18"{y^y2WXq^SjL4@C%YdfOp.) IL3I¦?.[G M˜ő+/ݒ|DY7_[8 ܺwv20rcP!Pg!psiKv!00]&?rvg8"(d2D:R=hV%`M'버 Eg͖&Ͷ>R!br$~[k+ ,;`bffa{viFQqs9 i4%`ғI(tfBN)sl< %&WAb P1ˆw%%m*(Q#Du$dHffC8'ﶹMU !6w_t $o6եuA3m;hu"!okCэs4=%# d ҫR hKF\vj;e3 VD_-|\nZYզUK⼯Q>>2R?U%ae`U89U#_Zµ|g{.';x'z+p*j#ڜkW ҕR}64HdDϛglEgN*!tmV$0 sC%\mk2EMIVpGh0ſK[P^Uٷ EY򶒜U'ZO$#6rѣؖP ks%Nu`9%l\Y`+:n]d(\i[vFUlƆ]zA׍N5pN HOp`l7QCln'E+w+,#MasVդ+O^昈Tʸ?2(D/@lAIb 0}kZ@%(5wt~{wif=oo/S}GGvoR '. `mԌuM =ըGi@#PFH=;a 7tOz~j;Ƿ^na]8[rUd9:zu%` SU'giKxs|ל;zҟ9ӳKaЊտ~0r G]ޮpc@gycPJ{pL~k1AD Ũ;YL|#ޚ)Q{cclAWNβ'',T'+M,"5VXCL3x=4-8e L98r^9Ѳ!#"mz d};َ.$o'&)u|dzv+%:&elshduSxء/̲K=[4Sn0l=ڠxݑo(Tkjz<3oD.e¨wEWV-Ų1qo4('aAk,v<*iEӭFS}//8j0ܯ$\[9lLtl:V;ZZTu8[ i}`1[rNyX[E"AMòNg!-zHuN_D'e^K ෯d]Loo·&Hv^nM,/.T z[2ZP5LDT#_IBDI|(|047$L3AD|L|j4bNe4n#; si9>3TiZi^O?MV3,.!dz(kԐ"eoC6EmOμ ~2DU ZQws琧~)7R9IhZxZwwH p9q {&nl>\/y8AZ:_2/‡lo)lf7Ks=y)2@D6P827}t<ͩOCj <ۚw5DN—T2~ocӺOK`&¨5Kf.}VRt0q v.Ju{GUk)s4GKB|ڪtE˒>ٽ4S15\5t?yw]z"svLQ6ou_~ /x矟ʸR}:LPZw(AV;z+{ ەw׍V)DÕ|=FYXyc#ijƞNW֢7JDyTsTjT+D}mD'anڂfeՠAv58/v ]i@ѽ>j}hg96~D':5Ԍɷ/ԃ1εn,Ѷ>Ǘ١.4"Bw؏(N9G)tyJZdڷU+ccGz)@,:4APYZq4לՆF.,bt#صsNչ^\q[ۣ&$j;\b9'H+(8*O=*ߍ` 5gx]J!ϒ>HwYn(d}}Ö$I o%~IAަiGuHe*Md#_ 9#2>΍e!Ĉݢ&/G+σ$D$jAv]Lyt[ܔaݵt.vSS;nFu,AImXᑃcÆzY~ 7?uws3,eᴜ"kRɄ fdam7LB8vqIxãGaƸ 蕞 7\QTj8RB+CY-dGZYx[0۳_Y ]F;lƒ:gbir1ގnfGQ2'z"$E_e؎!Y|Uv2Yז֎F3x9K;o*0}/gBȽĴVI7"3u=EaZYSV (tٶd;#j rwJ[Oг]6 B3p N{W\ņ7x۽4l0lofV\4C:s]2K{&|ӳZa8۫ !=l|8i SN^$;VuёL4Ƕa9G.M,G "O`r>}д:#LrA1?}'XIԐ>f}!QD-a!y>7eՃQDžѦv#*w *tαcCFЩofpr B'wPohwKߺO|o!/  JI;^ *P?5$i M^yݎI;"$Y ES*}m|'4E^xɯT>⪐׺ąTO~cwM ~6m2<A!Ϯz 'J<_v GA{ly}Ҡ/7k5phJgMAh#J\Ocup_2_Nڷq2*8?"ɠ8 ,g"NJq2|=tѳTRhD|W-.IW *kZ8W =Ĵ4m]mG]~Vݮz?;@ךk5G~6]C+ě9~y1Dg]?7ii0gj` ` e0YQ%{>M6!OUU[mU(Ж 4$HBl@lQ h%, 4FUj4` 4V"A$Dɋ)MkHLh355V @#&M4L}Fۢ қFj1$hRF6X&bڭbRRfR Q(h0TVZLQPc*4Rb0MZ$đJ1*4I@[)ch)"Th$ADh QhōFń1m&))Lh-,h(1b4dłI $,Q,AFM3R$cQDc%`̈13,TD0B"ƦL"H 2dƍْl(1hHX (آ4cchB%6J"ƂbcPIc#FmTFLD AIE(MI$RFX dH10 "dd0 BB d2C!SF0RY(` 4D1)#C) DTd 1dH X4bD" I 4T`"FZ1`0Pd()Q"Q2lPH 4RZ) DEIDhR&i2Z*b&c%F&&@a4-b4 F1IBJ ,01 d1$ cID "3+,((4X)55!MQHa f cBZEIKcشZ#LI&5&4m(L*1!EL lDX02FDH"$42)0&ƙ6Ha$Dl Ddԙcb2` ժM&hLh ,j42,b!5 @Jѱ(LYJ61I& #E F0 b6&@X&MTI,h@,2&JJf,d(ѣ#dəRF0!L%E"# h2QA$ICTfRZLlU$Dh&b2X1&̲b((EI,cb &Pj(* MD$cL‰,hFXe0f11 &% 1ȑ DFFI@ŘL`)P12@( -$dRY6*@1 AIai R!303&d҉hF$JeB1Q&̙fF RfebSHJIC2F1&LƔ$(M$h!CbRD@0#$ ɉL$JL 1@EHSIF@ !1hP015 CI Bb+" HXь lФHD2h )Ɍ!`1B`BLI,$))Y4) Y1BHcI)1 HB ( Yfc*,Z*6jDEDdƱ2cD#`!)(F(e1%$Df1@ƍHB$R D3"dFP# 5 Ȉ @H#$D҆Ș1 ,P$a!L(C(&$dYe%$1i1&daMF- (+ I# $0I ff! A D"HY$L̐A4BI$D$m*, &Blтe JI4cFJ !#DJfaLDMD ț(!H)h*2d%&,LŘ1Dƙ6S46MF1H) %c0"@6,61I#Fb (EEM&0&2d* ԚMAI a$Q i`)lcFBb2h#@`#d$hCHc`1cM&eQ%` jJڂcci"X֢4lQlTQlVhHX+D[EأZ",VѬbԛb*F6c[@V+j+FkX6ŴQZMF6mEUAjDVQQmcQX֣jjbT[TkTZ+EdbTkFm&̤&&&E 4)I4m%I`+flA43H ̒RlFlQ&DҚMQ HMIEؑF B#`l",l!Fld#@#""a2(6 llED,CLQ) M a AI1H&1( 1$%(H4S2cQh F1H(Z13&)"&63*(HE2)#ED*j5$h&1IF1R0 Q& 0j4Rm(ƣI 0HZcd(mX0Pi$TbQ1V6fj" Ia1I) ȨLAY1I* ɨ FbDŦbؓE&hbf"i`i(1&4cdj6*(I(6XLF[dF6 4HW" bF I ѢJRT$̘"4ccd0AJ"%E%!EQ1$@)4X beRAb6Je$*!1RkAd,$Z6# iEUeEdA10!hK,XID&Ljhl2!$X "I@j!fI3P.vcFƨjWeMh"C&B$I1#F&4@PE)&-rBAbI $ h"2L$ $%2Y5hɰ4(ƂvIe!HfɌRhTDȈ] ,Z@#6 ,`]rͣM7+HQu),;F2$!3jh0,IDh4Q""R0j F,b$"R ba%$ h؊1DP M B$cB Ƃ (I X,i5#IAj*J#A2h1fbfQR[4XQ$$"Г QJH* %!1Z#FѰe!6H3"6-"X5f Y*4C1b,($h4Il[ "%*i"ad#dH4 #DLS4Iɂ)H)6)"B`$&DBFDD )ł( "X)l(%dE%Ddƃ"HXdD(&TF2DX4SK#,`$cbœlF6MlL"C3A5 (ԘK%@ZATld--j*1 f M2QHIi& (cF4H 2jebƍ %!$l QBkEFdTA$J$bѴcc%$1#ZE&@bb j1DL)4dة0F( JL!`0%1!IE#d ib1mdXB$4`2TbL&iI2"ZJ#THb4QX "+ (2l֥ 2%iЕF hLT5 cAQQ"T$cJFMEb(KHX c"l5X%2RDPDFE2m" L5PTA& QI!Lj1DQ Z,2EJ4FQAQa1ŊHђɊ2f(6 "0$ 6BD1,Ƣ6HLd!Ie6M#$f)#b*ff%&B2IH&C S(hH!1li4(ZEMf̱(hDQdѐLfD[Ɍ0đHfR bZ R%1ETQ%$`LQc$!$iƊ),S 0 icBP&M cK4i0Y6D6dȰ$be ,Bd(2f&DcJbƌBCfJ(PbTi)BQ(ѠE$("ĘbD؄#-dQ(3F$)QLiT *4DJ#$k$AXlh!bBȘ &4YIH%5i0dŌXP`%)Mlda1#PQQ`El*4 Pb5$dCh4fkdQdS,"F"j)  ,X136LTQlلFAdRF&FѨj$d`1B4$IH RB` "4db$1F* cf%DK ĕd"`iRA %FThh cBFP"HXXd&fF"SH"hْQEIe%$2*")F (Da1hTX2bɒH` QhĖDԘJ$b#$!)2 Qa)1 !(1LQ 2D &ɑI$`(i*I cYHfE!cIB Ȥ cDl1f@hFQ0!#& Jcf"dJdLH02%(P1a(I FEE2I,6LbRL A#(Mc D͒B( %2, HXԅlD&aH͡"FF D4HbR1 `XD%"`,AdQ2V,#F#hb L4,"F6 4li12cdƂ" &ЅaH H)4Rb bM$ (I30lfFHC)H(X @("Y`-&dYH"$ ĘX,dD (F"e A 1a$ # DQXج[(bR2$lDXѲ"  "I)#!M(3AdIIh1A FBDZ!B)J,Hш# DEdCFʋF A$QAQdd1bMF #DK`̨0͌Q,A AFĚDC$1ĒZ  b"52Ѣ`BX"2RRb51PXE&RI0hĦQf641Q QF4E#(4K Acd#ḍLR&$ATD@$Z1FK2 1L&V0dB1LP!KF4lD6L%֪eWن QD[& `,B[s X[tTɦG d>HWWƸn$Ė$!"b׻Ym|?nބ١UcЀ``S4 Ki$0cJ@dUcFjB!֘U), QB EV X-qH2أQLdrpOX<0BbBZP0"D-aR )#5IHĐBFI@I 2F@*E"R&L@ dIL3kXUukL `od~I%I߶B9-620F"I"KF4QI( &04b) fQ$3 3fb1fa2DbH2 )3!b#QdԚ@$c? HLj$aDDD)IHH$$7wQ5 $4$b# "f2)"41j(E@QRX!4EIP LB%d؈h4)"cRIA Dh)0`CHEXRI$%`Sb6H( DD%I`1ѢѴeFaR0JƋ%F2h4hY, h*"c1Db(Ѥ͊Ԙ*4cE!1̲F&̔l11أDQ&SD%$ `F 3Fɀɒ()60&J5DJ)3;^IA"CFKFB*-1HY i%ѳ6 B4Q+**LF#$@6(eAɤ$H}~!JB4QFU,P q@m??ҟ骪 Y5p[LrӻsjHguu61Z"h(W5s-F6ѭ\*"̴֔x/ _+77h*[D<9TdTQlA^×\E:dkUͤ%# +߫kl}ki޶|-Α &$ i $HHX34(e$!Zi2 QPB?ȇ,$PsU! eɮ-VUpUYVҼ8h8*F%檳%/nDv\s30h"$4 %J [#5mF-b(j* (5BDV)"1DBX+b)5T%P%EHFأb6Ɠ`,Z((ZH!F4PAdeER4TXj"(Ql@hd"-H mLXTIF3)(hA(@AA2D т"d1BI$X MDD020`6FL "LFR- hc2V*5(ƌcjDX؀&%$F&0H&Eh!RcHEh4LP©5EbQQQRQH eEFa6THbѩm]R{ĶhXVJ_QbI *@3Ii$:oTbb$"LhHL) (XɖYb39;%)m\;%o1Dffɒ,ӬZŴG.m!(`˙wv#ܶ-EjJ4Fc[ch֊V*U_G{mnkkUm$FmAXDQhTXHQ$4i*6lEEѭbرY5&h6ɌX-ш6-cEFIkű1JEj5&5h4F6"Ŋ*UDѭ 5FTV#hXь4 d&$EhFK TT%PZ ɨ#EchL Lʊ2h0%F5e6(J_[V|$FR1$A%$FLP(͒ $HFHBTXA660i@,U(m&h4ɄIDLȯkojtX"ţlFch15DhZDQV6cF*%d*SQb[رEC *MDm,TZfر5U_m|U_'/DɢCIDJ0&,hA4PEH$B4lL5IHhɨX1bhآHAlX5AcMj*-L,j64F-"J&$ dLdYA&% iѵ"QP22Y(m$baI400SF& l bI,f` ?o{N4EU9a\]ʖ S\+mlp[`W&ʹ)_A>Y*H6f1Z$ClQiQQk&He,ə3 `Mik+UzB4<|KUz*N*ȓ~4%ueetK,ŁhibQ24 cFB3fIPM!  Db#`i`((I(ALF$Wu4!2Y F %J Ba$(h bDJ(!l`,X0D1ŃbH`mQ``$ ѐ"b#snā1Q XLQcRT ȆFMH ""fA1&E  DQ4bƤ2(2IS * A"LQRA;ww"8íaLnuiwrf2e;Iݜ۝vq;NĆ@G&Y@$ u vwS۱`w1BDu.5!΀\w]B%BHL)$h@R ($C& E$6 LK3$D@L0a !"I4ʔd$̈ą&0Ȃ %ELf C sLfT" C $I $PM0faAHIFZ4"d0$AL&$$Ȣ Lҙ6%J3@LHGlUh.%KnB 6] r઺a\%mxByRB+}+'#d-Ԩ~k-$zVq8' ΍{zc$⌄8e ?=g[dR۟#Gs^P}묧7h41cEׂ㑨L dO0",:~ g9W|ZHaŸ t "PGMŁ@%GH-V7>ġ+DIG]%$wCaACC$HZ:8N sվe?Tn)#q>C|sBF_$:wt :9G;NNGTfQ-UdP-U.FK[_jrfwN4#. PBCrȴ{;cĽUs׍u3CKJ",ѤEP[ripCD8sD Կr.oSBt@s2Xrym#.x-&D&E[ p\_r-ƛi:ҠxV;m1#yˌ8ܕb/84-C /VHK{%_*Țu(5@s*YrLCG}IqKGg(O_lISBhdFF{EZͯsw7Ӕr[ˡEU¸>409n :ZqXWgvgEidA?t9 w:{~_fZ [z3z'b:*wC+HwzU(_D--EYD ]έ&7VHUEn΄v8)1ηz헊U Jq%# NI9pˌ; -Y6e5!8N3l.'Yߢprn13(8$*q@>\(rQ `yRǓQm'ȬEIy8Cާ\%',f\D"3K%"l f[E TȅK~9%f`v{}ջEcGȊT'H hu:˿JN#o~gSz-duNEw*Xk儡 {tr]5hg]vըVʹ*-YKi8qkNTH/E'^JϳDܜMW u=*u-#* 4IDV@m'^RoۓsݕkW֡x'Bd( 9NTS(MKIa"HHbU_(-߹儈ng@>f&B7? <&FjaOy1>"推,չWb^cKlĶzK ?SUR q$1 [}WM<8z zCc/O]fԱ1yEfinXFe&T?-PXJq;X*K*ԎGE|vd^op qNȘn.Mknm/d0I;2n&rjs(6Y Fi0;§,,!>&Fjղ?SR!1 ';W@CFuԬSfIF>Vr'y(۬{;yg=fV#H+Y$Ph~8.`gZ9G>B|&w!G/"w;䃗 3Ě%,?r-"4M<̦B/!/bӄ.܌s= *zJk[̈~RZ.\q,o w(h9ėViVǢ0{+5U"87je8ěisfe)^vhɝkpgb TU8YJoJ̆H\Z8EqGo@ThEv瓸!%Q 'Iaoh%@֠RaF#>jurU=9f*.ZD8$H/@9iLj?긑Xz/} ^=x+-2OiOZܛp5C3cb]bep'Gъū5}h#RGCXUr:[ZK}^F@Ӹh6PQV]2<r*Thе՛w .ّZ SQ r̆ς:uȉF?IEeU7H^eC̢ؖR![3Ku +"(;2)10w!ickArx\g[^쫩?843TqhFŪs#:S13M GEŝtFbiMs9~5H5R&+/%E#/+/)|Q:ED6-U9T8:޻'.7Y-~k+k #`7Ǜ75Vw=5ҒYRG,ֈ[m}DUb H|.fr22dI+<5q;$U$m;}xFO 38X臢+#]:X#ZYIdW?Fݩ"`]+Ѣr#eg[%粤K/b{,w8Tt'AME4z.6$_C$Za8dBng^m3G8qؓ Gh>sAjQ7l$2ԔEh+!IY1ܹͩݿpt >v >bqh :1[a*G~3 ⱜdGcy; r2a< K󟃪6J|b__to FjpN<ӜdkY24MaKňWJ]y'Ҳ:uXMiSzA22SZL =lCZޯCv%挠Fʩ(`,{sأyc)SY|zNZK- ڳKK< ޛ8\<ԣ X&Xu!U-޴@NGež9$x91(̱.#~j#_* լ m OyCM|j5uCRL%7|~:ů/(N@!,BɊ"W:cfuDG- NS48h_Bٺ"#:‡ CZőSm ƻZEM" ?txg,Z~Oc^'r.ءkHL7]_%{Nwg[Z""e{<>.˧xƯBdz^S$1XTq_*t#VҌfd(X:B@Y!b HfTI!Q;YBX TE=sv^vV.-^cCG ?mG5*!@<N1Bu 4|Is5|>5Ȉqh )s͹YЄ7Z_gBj, gBD gOGB#m[;|ˁ*n)sA9sh4 {x-EY;s"P&NKg HErKy^!& 1c@SH5Ћ H5&xe<<*wZ.x!6%/5C@j@5kCy34 ֮e]e394%(@)RڇMIHJ9vj,|E }#:,yǎk5^iF(.jFn=;!_NTDaeJ[D)sFE(t?)vq6trwO)\wᤩr7Dּ>'ሌI&-4tyz93^fYT)@΅)z(Cr 2;SC"I$H%z+&,tl!D2"6Bi(Iԝ~ܩZ3M d(RR=<-"-;&z#%j&m3HA {V\ LJ蘆̐hX gt,q.NOFE~ՔZXӛGA<!" B;6z)/ޥ4#`@@/we QvA׹JZ)D57[P>Y HP_/T8k?Nٽé2V1\ kZ,-ӁmJtij)`tw^*p<9}Dv~ tCb'zTcot)g9CZbʩYRHfiD_U~*5=Ĭ=| V{Ԏ8#c$Q5C| 9ȈT;ws'Q rrI.KS@M>(̴Q߮mfŝc'$P}ln90gXmÌo ;T|#"l| u2yC !4 ϣ|If#h JHI$ 01T?WwzuuV-*TPFFRSE%$kz( ?W&8Pf≪|V%P謡8&$}H9i{sI.HI!+I|%!!5'<\ M$pnY_}u-7kOH,:#*aQlycwdYnjD0hDޙW]ĽҨF6 {[L 2r$Y4 <-݁%Y=FYbUwⴂ[2{"R8SA܅3ڇc[/z,yamúp?MP мoKI*lWt<8 9Q~!C2#HshO@t7w9ɣɽ=Kam{Q8n=gK#tH77?U;':]9"b 9;iTW:pi9Y9<^]YlvA?mv>97J(!Òf3)Q4Um^W*?ONCbA$F4i;.[naP59ǭګ|6m0oO.KZ5 ~U>7h`D7s*a_br6]ܡ,$X}}>@ CઓG%RC}/TirvzTRU5R1=64Tl=xS?K>06.%Y]4 i^s <{<6x@1/Y{ d; >nꥅp@chNϵ@*ȦT`B)&ޞos$Ŧ4OΠ$ 1쌩B sh''\G]Vs4O,W[j g-B5"GN: 3Yj_y*1^xCxPH8q8W!>(=Lޭݢg L{̑MܭhSrn3ܥ(#ʠC[]ZHw;may8zuT8D!h_`M|xܮ VqoH?U[ZWuCb U4v|ycQ$݈:TrAQj!΁Q)kx#4 WZEDj+ NJ>\Xm^Qf4S:1ވCOk$K"$,@P2Ҁi)1/ !Y)t}KM/(JL9fDBJ}#(c#ir6No#Z3B zF)n?("0I_Y Ls7.7ECw 7-PkҘeןȲPAw֙@Di[lNGs#ÒIJn'/8O'k)Ւxmw|3@o! .*ړG2!#H!w&QGChWNʻ$  GZ&]S]eyrt>j7f7C[_^P2[kEػT%"ےSuL-˸?@8kJ'V8@ˡ( n@MbJXle‹L0VRŒzAΚSWTL6-r'^KɷG'y k}WMZ7f@r?;m|Af)ytFŠVؘw|- {dF}붩 )Q ڡ> HitMgeTw2nFv xg6?8C ãOqmzz%x PvsIZ@'ݩڌ巤]t6wFq􁠍\9 Jmp;TC9+O!q=ҶAG`^\ܕAȰ^Fv6!:^m@R'- mސAo$!Hf]0]V̓ފMP:yאJfN)g不Ȍ"he] SC?ܔ xa@;nFYޒ0hM˭J7#H%\,W5#5\[(Nx?3G2NAs9|3Wkk᭘cӖ(ſVB'EQEgd.OQAy_ͩĽ Xc Ms>򴶟:zc79lsaBRÑ#a#_aNF4rxjNrxCYulm=?lDXHf#膜R*qO: 8yXA+qD@;TjkC=[ϓUK}i_cH5Q;|{E"؝8 FWɝ{Yą?z Nc$aZ >JByA uvS *z?ۇV;2$j:$m#C䨡 (fj4O\XY9ju!qA%*Bw}[{CZ1 I ][Y'wND *g{8#}#3~tbOZʝ@ ~EMy'#wځP!fh}Ì_澮^j< H ji 3 >܆ ̜]=U2{4mK|<Twd-5uy(@ωI|HEᔆY,EɷU'(pdV>j'LPކKT7%IiKٝ.N͉rY!L"{g-P:Gmҡꔅiv^Ab5AȅGI05<]X&bMf-"GěS*?3en$ GׂR,"H'ZQG"1&Zfbs)u9.] 2tXq`uH"78HTU4Y+6{B5ga;\S `el tXB٪)pfTB 2 u@mj`HaaޥI * lFA<8૵6RL[':tCb& SS5@4KǢزq]V5h Ud̵PQCY[ZwACVZuorkEȴHeU2-ߪ 3LrC E 8,06z;OqDrAw"BD@Fpŕ%e6*u=U% ȲئXT@H73Ҋ %uhкi%P՞̚%ފQi9] ܰt4xNWc#):Pk̜(].tKo7Qq࣢MY7@); zjOꐷLLuԬts4bLMzoO;gfz0(e&+hT5 ^@jz3ӣEFz\J^M L - *ٚUeMz>LIO+542JGIM؆h:rS{&+0 O,'GB۽ז5޵t|e1`羏Kz:\lCiͲziHW %ih7mKiF;*Y `}ǝ8T nnUQfNCmV},ާ}LYw ٭2FњMOjS[&Tݚa"CB=wupU,fD@։3/+2SN>>:.)!~sݙ 'jfe TR1al|k*גښw!\}]ƦNY.U잩ߖE}SQGMCWȆCc'a\sT@sW{JYcEY SYtZ'W/ T$;UzyQeeCZ 뾠=H{,OѲۜ*N8h0Hi& Lș$iڂ¸svхNt'SwsiOO3-'5&ҙg:l`T0IОINˮdҥPjnr $,%I8;23C]u{I<`nlVK՝DmY֓3 +_ezUK{(A8⬲!!`JNR}$j:Bqs%Ǔ/؝򦤴C! kE2yrqHy9xfWm,,3&łL|xvEZaEOSSOFLTu'-)`#Q^Us9KОM{}kMY(Wei; ?vgϔ z 鞪eldNkT M9u?ueX%qo ' ֚TOjRO4/Hx/? `* |Q!n5?,e=Pއ:Ob4-6Zm/MI5ACJgjq 2me5GXk`~[+;%Wc&GI\U ЦM0}]+uӏ? 38f-S1tٞ͘(}Dꔪ"S6<1G}/a> RE`"o7'_],%k&ݗek^/OTg>`` s>vșs`|z7y`cn >)Ia[7`kTʝʁ>ȁwI!Ӓ &w0D?^.a]Sҥ羂ݶR^X?iz,=.Gs%^ɓ+{UIr{gbj j!!D | }t!0,hYY4o=[52z>Wוx̅jS!r\L+:ut%Zi|fP CTxϞ&χѓkFΛLCŅUSAͲ3_`Νɨ %?v 3͔* >r`/}9: 40&umw@t1~k纽~({.V ,5Ϥ3QE^v^sG*n Py XX(V)9*5Rog벃 3g{+ 0uQ<!THmedʅ*!I?&!dLM4/AEX~6sU Yzle2K%ox'Re|;T~{HRjzXuv/@RNm o]TO&s_pV<-Qbf-}Gs] )*3wvE9-QS,.SSi}ssqgꌙhkb8>l/`ٽ>.H,;hdѣيRt;GkXup KdBj).6%43uy[rz.Pɽ> CI27{9 "pK$MMw;ۓ r>l黟%ڙ既KJAM;hgmOҒaхZ9(<hIŐȁ$ bYә/&[ P0mdmVdyS2,K6E؅DO,-zuBJIn t I{fe2䔝hSšs!fOU%8!ri\K6Y E͍*tsz5DY T,RmS<ً98$uhxKÝ a3/d);F{w 2wrFДT(!+u"2earvXgժW~Y̊Urlls&VC ş,)4XY8R=݅I0z&/pKاt!Νu{_J{6gx0 tQ) YObi6KC)$広<+Bu!s ށ˚^م3̗[ٵ}(Xb+nK-$ȀoC͗0V9Ӫ%T9' x͘z.| *RLORvS0aR\aI)pgKsfu$a 3&_N'{'k̷豓ֺmAz!{/]_ ,IHd`RtX>L:ꡋ?930ߔh)9aYF6 b& +m̆NE0Y\y$2t!$:Z砹qQHmMhY "\ 5)4pXdN Jи7[?nw,Ɋ)tJ_U& 'lzؘya޵C"Oq vԅ̞>*8سzh뢯.LCJBԁ&(:&/R<4֝іdd, rhdpad`*(.ao'$4/cX]:hpb",%0tB:S:~g>k%i{O$3 {"œdS{4ȥꆻ RSu3uLVj,{86 ,S唐2VL칆~љf ;Re'?I^Iڌe*u2ʤTT, e7ha\6l;SѽP݅v [=BjusgI&]ύ֙YfL 'c bËސ(\`g(TPfT:ok՝?ʆO0d5xTi+-nP$X MnB<}v~IGiƊɪvIfpnOK{ Y83C BY'C *X~_A:u!^(nIg&J˜蹽 }?iLҳC39!@!Kӛ ->!ə唩O&Q*RmdӪ6ƥySzw] T^j=/ NIa΅60z&f/ne YhjfWf7׋$raKG1e÷=(%3Z=JEJe}d! j0=}5OēBw&Bt<Aym9!zR9B-,&Km_aԞk_J/{PY36Id,UXωuBv& ^*jk&;ɀZnVD/`Z8T<+VKk@Þ֛9P74u%.yӯuY@K$Rœ)5̑IN)a0߅X<ɑZXcY)[B콆:\/]SBjb픚],#,{Nf0ˮւ \P.#3uؘ&TYɅ!_$Cu6i$Cv,)dJiARmAo`&Dǚ%*S Y';4q߈ki4:OTM %ghʍ,82͚Cs , z2N9r\^ÒJCLkAC)؜P^69K 93'SW2Y ,>YηR,aN60IڷXPidyQdXfD&.a߿L2Us"쮌*ώkBPLd|ɞxucMo3&dPe#P΁-A̜E9+P20RpuiWL*Cm9 I)'6t2X`]SN Rhr赡Tadt3Σ 0{VZ\( }H|n8pzMX/K\TYq7(ϷȚ\hdd8W+L'qσ x5sw ;v-#M;L,S"aAHE!ep 2ʮwtU3WU$ FZɒtqu#dRN*qKW{2Wlj{dOd8~-6&cy & TdcTٺ߻]KE;2H=3i6F8ZVU2o88cf)ؘ37n{N: ȆٔF(h}jQLЄaPOJM꥾*taW1CR}7:ŶF)'w9,Ŋ<{,gluڗGߕ 6ו5&Ta+j (d@gzUf.|`˹3=/$0X,rG$Ae{R-u[.!{!ucӮrNI2'S:P-W8֔à ?M:QAEUwh#U=\fzTI§vk]3p1RM2wuM}<텾59SfnHtd'eߴ2kcp.f%ɳ5@Ȇ,&6LN5Z%WF).jʜv^RUYJ&6.LR;< Ŋ(u]љ73]Xu>ULIk&RC&cii`j2^q欬ukᗒoyB&Z&І%a$$éa;U T9Z`k!k <7sX&AafRdBL\8sUWRK'77鍶OEzd^j)N僇mΚ0€e,g==piT%s CR˓ĺLfHt4};͎,ej Z'e̘kނW3hS5a]x n*8yJg&f@[ĝ9f?Y(𾟧+j/bmaN!Jl$3ah<+7n*~|e˓fZ0Ux;*??J\_.7P~z{mpgWV`@І-r"ϩYt84.tLWvFtGׅEmҬؤdE}zOo9k.@kRv?FMHR'}5[EfЄ$"=sQPx3%b]>4fL5Z8_c#>/u T7"~E-s; @*9+40Y՞SM'g(hiȬ%UdO$6(v*3Y"~lhg."&RgWW;ׇAbF֥k]b@׽@[\u5a8caZB{87x,g0:!o*^i d+d{ C;2'ɣ)SsءI4k#~4iCk?,يo~fPY86.TGeS6mχoEʒ¥_kN__O&acݖ=*N%1 ^CeTC暆 "+9qʪݓd`jfdwT%+(ELϟgMw53#fywW?ܟUDZso4>SY%P<>ay 'ڹX]ÙSeBoBtQu-7[ *K)E=nXfV1C߃r iㅫܳ tT;-xRʧ4u -yR8-okdP}] s~eMn+v@}7 %3YUepw!|^Ty$5\gkІBgGz ?\K5B;GCYD uy#R;&%Fa8PZЇ"A pI8B`T^@/.k=+,妠*= ԋE9yʐ"=MqL—sspMd uZF$gt@h?D [0;t)@QqϿslmuY>sG,E+".FnI;P7.*0JIxdzؚ!YLhgdI³řF/=QÆ.bb8̒3{]Β &W#4i2̿LCiMn3b ]9ѽFQKِg~'?{lu0zhShHY{]܂!_U䞷wrdX:^݇9ӭ0gnչ -D}C_ݡd䜞b^~R)lY sޝ}Z.K$q]BClx$lubridate/R/0000755000176200001440000000000013263152652012433 5ustar liggesuserslubridate/R/hidden.r0000644000176200001440000000030713103077700014042 0ustar liggesusers#' Internal page for hidden aliases #' #' For S4 methods that require a documentation entry but only clutter the index. #' #' @usage NULL #' @format NULL #' @keywords internal hidden_aliases <- NULL lubridate/R/ops-addition.r0000644000176200001440000001052313263120555015206 0ustar liggesusers#' @include timespans.r #' @include durations.r #' @include intervals.r #' @include periods.r #' @include Dates.r #' @include difftimes.r #' @include numeric.r #' @include POSIXt.r NULL add_duration_to_duration <- function(dur2, dur1) new("Duration", dur1@.Data + dur2@.Data) add_duration_to_date <- function(dur, date) { if (is.Date(date)) { date <- as.POSIXct(date) ans <- with_tz(date + dur@.Data, "UTC") if (all(is.na(ans))) return(as.Date(ans)) # ALL NAs if (all(hour(na.omit(ans)) == 0 & minute(na.omit(ans)) == 0 & second(na.omit(ans)) == 0)) { return(as.Date(ans)) } return(ans) } new <- date + dur@.Data attr(new, "tzone") <- tz(date) reclass_date(new, date) } add_period_to_period <- function(per2, per1) { new("Period", per1@.Data + per2@.Data, year = per1@year + per2@year, month = per1@month + per2@month, day = per1@day + per2@day, hour = per1@hour + per2@hour, minute = per1@minute + per2@minute) } add_period_to_date <- function(per, date) { lt <- as.POSIXlt(date) ## add months and years with no backwards rollover ms <- month(per) + year(per) * 12 lt <- add_months(lt, ms) new <- update(lt, days = mday(lt) + per@day, hours = hour(lt) + per@hour, minutes = minute(lt) + per@minute, seconds = second(lt) + per@.Data) if (is.Date(date) && sum(new$sec, new$min, new$hour, na.rm = TRUE) != 0) return(new) reclass_date(new, date) } add_months <- function(mt, mos) { mt$mon <- mt$mon + mos ndays <- as.numeric(format.POSIXlt(mt, "%d", usetz = FALSE)) mt$mon[mt$mday != ndays] <- NA mt } add_number_to_duration <- function(num, dur) { new("Duration", dur@.Data + num) } add_number_to_period <- function(num, per) { slot(per, ".Data") <- per@.Data + num per } #' @export setMethod("+", signature(e1 = "Duration", e2 = "Duration"), function(e1, e2) add_duration_to_duration(e2, e1)) #' @export setMethod("+", signature(e1 = "Duration", e2 = "Date"), function(e1, e2) add_duration_to_date(e1, e2)) #' @export setMethod("+", signature(e1 = "Duration", e2 = "difftime"), function(e1, e2) add_duration_to_duration(as.duration(e2), e1)) #' @export setMethod("+", signature(e1 = "Duration", e2 = "numeric"), function(e1, e2) add_number_to_duration(e2, e1)) #' @export setMethod("+", signature(e1 = "Duration", e2 = "POSIXct"), function(e1, e2) add_duration_to_date(e1, e2)) #' @export setMethod("+", signature(e1 = "Duration", e2 = "POSIXlt"), function(e1, e2) add_duration_to_date(e1, e2)) #' @export setMethod("+", signature(e1 = "Period", e2 = "Period"), function(e1, e2) add_period_to_period(e2, e1)) #' @export setMethod("+", signature(e1 = "Period", e2 = "Date"), function(e1, e2) add_period_to_date(e1, e2)) #' @export setMethod("+", signature(e1 = "Period", e2 = "numeric"), function(e1, e2) add_number_to_period(e2, e1)) #' @export setMethod("+", signature(e1 = "Period", e2 = "POSIXct"), function(e1, e2) add_period_to_date(e1, e2)) #' @export setMethod("+", signature(e1 = "Period", e2 = "POSIXlt"), function(e1, e2) add_period_to_date(e1, e2)) #' @export setMethod("+", signature(e1 = "Date", e2 = "Duration"), function(e1, e2) add_duration_to_date(e2, e1)) #' @export setMethod("+", signature(e1 = "Date", e2 = "Period"), function(e1, e2) add_period_to_date(e2, e1)) #' @export setMethod("+", signature(e1 = "difftime", e2 = "Duration"), function(e1, e2) as.difftime(e2, units = "secs") + e1) #' @export setMethod("+", signature(e1 = "numeric", e2 = "Duration"), function(e1, e2) add_number_to_duration(e1, e2)) #' @export setMethod("+", signature(e1 = "numeric", e2 = "Period"), function(e1, e2) add_number_to_period(e1, e2)) #' @export setMethod("+", signature(e1 = "POSIXct", e2 = "Duration"), function(e1, e2) add_duration_to_date(e2, e1)) #' @export setMethod("+", signature(e1 = "POSIXct", e2 = "Period"), function(e1, e2) add_period_to_date(e2, e1)) #' @export setMethod("+", signature(e1 = "POSIXlt", e2 = "Duration"), function(e1, e2) add_duration_to_date(e2, e1)) #' @export setMethod("+", signature(e1 = "POSIXlt", e2 = "Period"), function(e1, e2) add_period_to_date(e2, e1)) lubridate/R/ops-subtraction.r0000644000176200001440000000216213201152061015735 0ustar liggesusers#' @include timespans.r #' @include durations.r #' @include intervals.r #' @include periods.r #' @include Dates.r #' @include difftimes.r #' @include POSIXt.r NULL subtract_interval_from_date <- function(int, date) { end <- int@start + int@.Data dur <- as.duration(int) add_duration_to_date(-dur, date) } #' @export setMethod("-", signature(e1 = "Duration", e2 = "missing"), function(e1, e2) multiply_duration_by_number(e1, -1)) #' @export setMethod("-", signature(e1 = "Interval", e2 = "missing"), function(e1, e2) multiply_interval_by_number(e1, -1)) #' @export setMethod("-", signature(e1 = "Period", e2 = "missing"), function(e1, e2) multiply_period_by_number(e1, -1)) #' @export setMethod("-", signature(e1 = "ANY", e2 = "Duration"), function(e1, e2) e1 + (-e2)) #' @export setMethod("-", signature(e1 = "Duration", e2 = "ANY"), function(e1, e2) e1 + (-e2)) #' @export setMethod("-", signature(e1 = "ANY", e2 = "Period"), function(e1, e2) e1 + (-e2)) #' @export setMethod("-", signature(e1 = "Period", e2 = "ANY"), function(e1, e2) e1 + (-e2)) lubridate/R/periods.r0000644000176200001440000005605013236356713014275 0ustar liggesusers#' @include timespans.r #' @include util.r #' @include durations.r NULL check_period <- function(object) { errors <- character() ## if (!is.numeric(object@.Data)) { ## msg <- "seconds (.Data) value must be numeric." ## errors <- c(errors, msg) ## } ## if (!is.numeric(object@year)) { ## msg <- "year value must be numeric." ## errors <- c(errors, msg) ## } ## if (!is.numeric(object@month)) { ## msg <- "year value must be numeric." ## errors <- c(errors, msg) ## } ## if (!is.numeric(object@day)) { ## msg <- "year value must be numeric." ## errors <- c(errors, msg) ## } ## if (!is.numeric(object@hour)) { ## msg <- "year value must be numeric." ## errors <- c(errors, msg) ## } ## if (!is.numeric(object@minute)) { ## msg <- "year value must be numeric." ## errors <- c(errors, msg) ## } length(object@.Data) -> n lengths <- c(length(object@year), length(object@month), length(object@day), length(object@hour), length(object@minute)) if (any(lengths != n)) { msg <- paste("Inconsistent lengths: year = ", lengths[1], ", month = ", lengths[2], ", day = ", lengths[3], ", hour = ", lengths[4], ", minute = ", lengths[5], ", second = ", n, sep = "") errors <- c(errors, msg) } values <- c(object@year, object@month, object@day, object@hour, object@minute) values <- na.omit(values) if (sum(values - trunc(values))) { msg <- "periods must have integer values" errors <- c(errors, msg) } if (length(errors) == 0) TRUE else errors } #' Period class #' #' Period is an S4 class that extends the [Timespan-class] class. #' Periods track the change in the "clock time" between two date-times. They #' are measured in common time related units: years, months, days, hours, #' minutes, and seconds. Each unit except for seconds must be expressed in #' integer values. #' #' The exact length of a period is not defined until the period is placed at a #' specific moment of time. This is because the precise length of one year, #' month, day, etc. can change depending on when it occurs due to daylight savings, #' leap years, and other conventions. A period can be #' associated with a specific moment in time by coercing it to an #' [Interval-class] object with [as.interval()] or by adding #' it to a date-time with "+". #' #' Periods provide a method for measuring generalized timespans when we wish to #' model clock times. Periods will attain intuitive results at this task even #' when leap years, leap seconds, gregorian days, daylight savings changes, and #' other events happen during the period. #' #' Because Period represents imprecise amount of time it cannot be compared to #' precise timestamps as Durations and Intervals are. You need to explicitely #' conver to durations. See [Duration-class]. #' #' The logic that guides arithmetic with periods can be unintuitive. Starting #' with version 1.3.0, \pkg{lubridate} enforces the reversible property of arithmetic #' (e.g. a date + period - period = date) by returning an NA if you create an #' implausible date by adding periods with months or years units to a date. For #' example, adding one month to January 31st, 2013 results in February 31st, #' 2013, which is not a real date. \pkg{lubridate} users have argued in the past that #' February 31st, 2013 should be rolled over to March 3rd, 2013 or rolled back #' to February 28, 2013. However, each of these corrections would destroy the #' reversibility of addition (Mar 3 - one month == Feb 3 != Jan 31, Feb 28 - one #' month == Jan 28 != Jan 31). If you would like to add and subtract months in a #' way that rolls the results back to the last day of a month (when appropriate) #' use the special operators, \code{\link{\%m+\%}}, \code{\link{\%m-\%}} or a #' bit more flexible [add_with_rollback()]. #' #' Period class objects have six slots. 1) .Data, a numeric object. The #' apparent amount of seconds to add to the period. 2) minute, a numeric object. #' The apparent amount of minutes to add to the period. 3) hour, a numeric object. #' The apparent amount of hours to add to the period.4) day, a numeric object. #' The apparent amount of days to add to the period.5) month, a numeric object. #' The apparent amount of months to add to the period. 6) year, a numeric object. #' The apparent amount of years to add to the period. #' #' @export #' @keywords internal setClass("Period", contains = c("Timespan", "numeric"), slots = c(year = "numeric", month = "numeric", day = "numeric", hour = "numeric", minute = "numeric"), prototype = prototype(year = 0, month = 0, day = 0, hour = 0, minute = 0), validity = check_period) #' @name hidden_aliases #' @aliases Arith,ANY,Period-method Arith,Duration,Period-method #' Arith,Period,Duration-method Compare,Period,Duration-method #' Compare,numeric,Period-method Compare,difftime,Period-method #' Compare,Period,difftime-method Compare,Period,Period-method #' Compare,Period,character-method Compare,Period,numeric-method #' Compare,character,Period-method second,Period-method second<-,Period-method #' minute,Period-method minute<-,Period-method hour,Period-method #' hour<-,Period-method Arith,Period,ANY-method day,Period-method #' day<-,Period-method month,Period-method month<-,Period-method #' year,Period-method year<-,Period-method date,Period-method #' date<-,Period-method as.numeric,Period-method show,Period-method #' c,Period-method rep,Period-method [,Period-method #' [<-,Period,ANY,ANY,Period-method [[,Period-method #' [[<-,Period,ANY,ANY,Period-method $,Period-method $<-,Period-method #' as.difftime,Period-method as.character,Period-method #' +,Period,Duration-method +,Period,Interval-method +,Period,Period-method #' +,Period,Date-method +,Date,Period-method +,Period,difftime-method #' +,difftime,Period-method +,Period,numeric-method +,numeric,Period-method #' +,Period,POSIXct-method +,POSIXct,Period-method +,Period,POSIXlt-method #' +,POSIXlt,Period-method /,Period,Duration-method /,Period,Interval-method #' /,Period,Period-method /,Period,difftime-method /,difftime,Period-method #' /,Period,numeric-method /,numeric,Period-method *,Period,ANY-method #' *,ANY,Period-method -,Period,ANY-method -,Period,missing-method #' -,ANY,Period-method %%,Period,Duration-method %%,Period,Interval-method #' %%,Period,Period-method >,Period,Period-method >=,Period,Period-method #' ==,Period,Period-method !=,Period,Period-method <=,Period,Period-method #' <,Period,Period-method >,Period,Duration-method >=,Period,Duration-method #' ==,Period,Duration-method !=,Period,Duration-method #' <=,Period,Duration-method <,Period,Duration-method >,Duration,Period-method #' >=,Duration,Period-method ==,Duration,Period-method #' !=,Duration,Period-method <=,Duration,Period-method #' <,Duration,Period-method >,Period,numeric-method >=,Period,numeric-method #' ==,Period,numeric-method !=,Period,numeric-method <=,Period,numeric-method #' <,Period,numeric-method >,numeric,Period-method >=,numeric,Period-method #' ==,numeric,Period-method !=,numeric,Period-method <=,numeric,Period-method #' <,numeric,Period-method !=,Duration,Period !=,Period,Duration #' !=,Period,Period !=,Period,numeric !=,numeric,Period %%,Period,Duration #' %%,Period,Interval %%,Period,Period *,ANY,Period *,Period,ANY -,ANY,Period #' -,Period,Interval -,Period,missing /,numeric,Period <,Duration,Period #' <,Period,Duration <,Period,Period <,Period,numeric <,numeric,Period #' <=,Duration,Period <=,Period,Duration <=,Period,Period <=,Period,numeric #' <=,numeric,Period ==,Duration,Period ==,Period,Duration ==,Period,Period #' ==,Period,numeric ==,numeric,Period >,Duration,Period >,Period,Duration #' >,Period,Period >,Period,numeric >,numeric,Period >=,Duration,Period #' >=,Period,Duration >=,Period,Period >=,Period,numeric >=,numeric,Period NULL setMethod("initialize", "Period", function(.Object, ...) { dots <- list(...) names(dots)[!nzchar(allNames(dots))] <- ".Data" len <- max(unlist(lapply(dots, length), F, F)) for (nm in slotNames(.Object)) { slot(.Object, nm) <- if (is.null(obj <- dots[[nm]])) { rep.int(0L, len) } else { if (length(obj) < len) rep_len(obj, len) else obj } } validObject(.Object) .Object }) #' @export setMethod("show", signature(object = "Period"), function(object) { print(format(object)) }) #' @export format.Period <- function(x, ...) { if (length(x@.Data) == 0) return("Period(0)") show <- vector(mode = "character") na <- is.na(x) show <- paste(x@year, "y ", x@month, "m ", x@day, "d ", x@hour, "H ", x@minute, "M ", x@.Data, "S", sep = "") start <- regexpr("[-1-9]|(0\\.)", show) show <- ifelse(start > 0, substr(show, start, nchar(show)), "0S") show[na] <- NA show } #' @export xtfrm.Period <- function(x) { xtfrm(period_to_seconds(x)) } #' @export setMethod("c", signature(x = "Period"), function(x, ...) { elements <- lapply(list(...), as.period) seconds <- c(x@.Data, unlist(lapply(elements, slot, ".Data"))) years <- c(x@year, unlist(lapply(elements, slot, "year"))) months <- c(x@month, unlist(lapply(elements, slot, "month"))) days <- c(x@day, unlist(lapply(elements, slot, "day"))) hours <- c(x@hour, unlist(lapply(elements, slot, "hour"))) minutes <- c(x@minute, unlist(lapply(elements, slot, "minute"))) new("Period", seconds, year = years, month = months, day = days, hour = hours, minute = minutes) }) #' @export setMethod("rep", signature(x = "Period"), function(x, ...) { new("Period", rep(x@.Data, ...), year = rep(x@year, ...), month = rep(x@month, ...), day = rep(x@day, ...), hour = rep(x@hour, ...), minute = rep(x@minute, ...)) }) #' @export setMethod("[", signature(x = "Period"), function(x, i, j, ..., drop = TRUE) { new("Period", x@.Data[i], year = x@year[i], month = x@month[i], day = x@day[i], hour = x@hour[i], minute = x@minute[i]) }) #' @export setMethod("[[", signature(x = "Period"), function(x, i, j, ..., exact = TRUE) { new("Period", x@.Data[i], year = x@year[i], month = x@month[i], day = x@day[i], hour = x@hour[i], minute = x@minute[i]) }) #' @export setMethod("[<-", signature(x = "Period", value = "Period"), function(x, i, j, ..., value) { x@.Data[i] <- value@.Data x@year[i] <- value@year x@month[i] <- value@month x@day[i] <- value@day x@hour[i] <- value@hour x@minute[i] <- value@minute x }) #' @export setMethod("[[<-", signature(x = "Period", value = "Period"), function(x, i, j, ..., value) { x@.Data[i] <- value@.Data x@year[i] <- value@year x@month[i] <- value@month x@day[i] <- value@day x@hour[i] <- value@hour x@minute[i] <- value@minute x }) #' @export setMethod("$", signature(x = "Period"), function(x, name) { if (name == "second") name <- ".Data" slot(x, name) }) #' @export setMethod("$<-", signature(x = "Period"), function(x, name, value) { if (name == "second") name <- ".Data" slot(x, name) <- rep_len(value, length(x)) x }) #' Create or parse period objects #' #' `period()` creates or parses a period object with the specified values. #' #' Within a Period object, time units do not have a fixed length (except for #' seconds) until they are added to a date-time. The length of each time unit #' will depend on the date-time to which it is added. For example, a year that #' begins on 2009-01-01 will be 365 days long. A year that begins on 2012-01-01 #' will be 366 days long. When math is performed with a period object, each unit #' is applied separately. How the length of a period is distributed among its #' units is non-trivial. For example, when leap seconds occur 1 minute is longer #' than 60 seconds. #' #' Periods track the change in the "clock time" between two date-times. They #' are measured in common time related units: years, months, days, hours, #' minutes, and seconds. Each unit except for seconds must be expressed in #' integer values. #' #' Besides the main constructor and parser [period()], period objects can also #' be created with the specialized functions [years()], [months()], [weeks()], #' [days()], [hours()], [minutes()], and [seconds()]. These objects can be added #' to and subtracted to date-times to create a user interface similar to object #' oriented programming. #' #' Note: Arithmetic with periods can results in undefined behavior when #' non-existent dates are involved (such as February 29th). Please see #' [Period-class] for more details and \code{\link{\%m+\%}} and #' [add_with_rollback()] for alternative operations. Note: Arithmetic with #' periods can results in undefined behavior when non-existent dates are #' involved (such as February 29th in non-leap years). Please see [Period-class] #' for more details and \code{\link{\%m+\%}} and [add_with_rollback()] for #' alternative operations. #' #' @name period #' @aliases periods #' @param num a numeric or character vector. A character vector can specify #' periods in a convenient shorthand format or ISO 8601 specification. All #' unambiguous name units and abbreviations are supported, "m" stands for #' months, "M" for minutes unless ISO 8601 "P" modifier is present (see #' examples). Fractional units are supported but the fractional part is always #' converted to seconds. #' @param units a character vector that lists the type of units to be used. The #' units in units are matched to the values in num according to their #' order. When `num` is character, this argument is ignored. #' @param ... a list of time units to be included in the period and their #' amounts. Seconds, minutes, hours, days, weeks, months, and years are #' supported. Normally only one of `num` or `...` are present. If both are #' present, the periods are concatenated. #' @param x Any R object for `is.periods` and a numeric value of the number of #' units for elementary constructors. With the exception of seconds(), x must #' be an integer. #' @param abbreviate Ignored. For consistency with S3 generic in base namespace. #' @seealso [Period-class], [period()], \code{\link{\%m+\%}}, #' [add_with_rollback()] #' @return a period object #' @keywords chron classes #' @examples #' #' ### Separate period and units vectors #' #' period(c(90, 5), c("second", "minute")) #' # "5M 90S" #' period(-1, "days") #' period(c(3, 1, 2, 13, 1), c("second", "minute", "hour", "day", "week")) #' period(c(1, -60), c("hour", "minute")) #' period(0, "second") #' #' ### Units as arguments #' #' period (second = 90, minute = 5) #' period(day = -1) #' period(second = 3, minute = 1, hour = 2, day = 13, week = 1) #' period(hour = 1, minute = -60) #' period(second = 0) #' period(c(1, -60), c("hour", "minute"), hour = c(1, 2), minute = c(3, 4)) #' #' ### Lubridate style parsing #' #' period("2M 1sec") #' period("2hours 2minutes 1second") #' period("2d 2H 2M 2S") #' period("2days 2hours 2mins 2secs") #' period("2 days, 2 hours, 2 mins, 2 secs") #' # Missing numerals default to 1. Repeated units are added up. #' duration("day day") #' #' ### ISO 8601 parsing #' #' period("P10M23DT23H") # M stands for months #' period("10DT10M") # M stands for minutes #' period("P3Y6M4DT12H30M5S") # M for both minutes and months #' period("P23DT60H 20min 100 sec") # mixing ISO and lubridate style parsing #' #' ### Comparison with characters (from v1.6.0) #' #' duration("day 2 sec") > "day 1sec" #' #' ### Elementary Constructors #' #' x <- ymd("2009-08-03") #' x + days(1) + hours(6) + minutes(30) #' x + days(100) - hours(8) #' #' class(as.Date("2009-08-09") + days(1)) # retains Date class #' as.Date("2009-08-09") + hours(12) #' class(as.Date("2009-08-09") + hours(12)) #' # converts to POSIXt class to accomodate time units #' #' years(1) - months(7) #' c(1:3) * hours(1) #' hours(1:3) #' #' # sequencing #' y <- ymd(090101) # "2009-01-01 CST" #' y + months(0:11) #' #' # compare DST handling to durations #' boundary <- ymd_hms("2009-03-08 01:59:59", tz="America/Chicago") #' boundary + days(1) # period #' boundary + ddays(1) # duration #' @export period <- function(num = NULL, units = "second", ...) { nums <- list(...) if (is.character(num)) { parse_period(num) } else if (!is.null(num) && length(nums) > 0) { c(.period_from_num(num, units), .period_from_units(nums)) } else if (!is.null(num)) { .period_from_num(num, units) } else if (length(nums)) { .period_from_units(nums) } else { stop("No valid values have been passed to 'period' constructor") } } parse_period <- function(x) { out <- .Call(C_parse_period, as.character(x)) new("Period", out[1, ], minute = out[2, ], hour = out[3, ], day = out[4, ] + 7L*out[5, ], month = out[6, ], year = out[7, ]) } .period_from_num <- function(num, units) { if (!is.numeric(num)) { stop(sprintf("First argument to `period` constructor must be character or numeric. Supplied object of class '%s'", class(num))) } if (is.interval(num)) stop("Interval objects cannot be used as input to 'period' constructor. Plese use 'as.period'.") if (length(units) %% length(num) != 0) stop("Arguments `num` and `units` must have same length") num <- num + rep(0, length(units)) unit <- standardise_date_names(units) pieces <- setNames(as.list(num), unit) defaults <- list(second = 0, minute = 0, hour = 0, day = 0, week = 0, month = 0, year = 0) pieces <- c(pieces, defaults[setdiff(names(defaults), names(pieces))]) pieces$day <- pieces$day + 7 * pieces$week new("Period", pieces$second, year = pieces$year, month = pieces$month, day = pieces$day, hour = pieces$hour, minute = pieces$minute) } .period_from_units <- function(units) { pieces <- data.frame(lapply(units, as.numeric)) ## fixme: syncronize this with the initialize method names(pieces) <- standardise_date_names(names(pieces)) defaults <- data.frame( second = 0, minute = 0, hour = 0, day = 0, week = 0, month = 0, year = 0 ) if (nrow(pieces) == 0) defaults <- defaults[0, ] pieces <- cbind(pieces, defaults[setdiff(names(defaults), names(pieces))]) ## pieces <- pieces[c("year", "month", "week", "day", "hour", "minute", "second")] pieces$day <- pieces$day + pieces$week * 7 na <- is.na(rowSums(pieces)) pieces$second[na] <- NA ## if any of supplied pieces is NA whole vector should be NA new("Period", pieces$second, year = pieces$year, month = pieces$month, day = pieces$day, hour = pieces$hour, minute = pieces$minute) } #' @rdname period #' @examples #' is.period(as.Date("2009-08-03")) # FALSE #' is.period(period(months= 1, days = 15)) # TRUE #' @export is.period <- function(x) is(x, "Period") #' @export seconds minutes hours days weeks years milliseconds microseconds microseconds nanoseconds picoseconds #' @rdname period seconds <- function(x = 1) period(second = x) #' @rdname period minutes <- function(x = 1) period(minute = x) #' @rdname period hours <- function(x = 1) period(hour = x) #' @rdname period days <- function(x = 1) period(day = x) #' @rdname period weeks <- function(x = 1) period(week = x) #' @rdname period years <- function(x = 1) period(year = x) #' @rdname period milliseconds <- function(x = 1) seconds(x/1000) #' @rdname period microseconds <- function(x = 1) seconds(x/1000000) #' @rdname period nanoseconds <- function(x = 1) seconds(x/1e9) #' @rdname period picoseconds <- function(x = 1) seconds(x/1e12) #' @rdname period #' @export months.numeric <- function(x, abbreviate) { period(month = x) } #' Contrive a period to/from a given number of seconds #' #' `period_to_seconds()` approximately converts a period to seconds assuming #' there are 365.25 days in a calendar year and 365.25/12 days in a month. #' #' @param x A numeric object. The number of seconds to coerce into a period. #' @return A number (period) that roughly equates to the period (seconds) given. #' @export period_to_seconds <- function(x) { x@.Data + 60 * x@minute + 60 * 60 * x@hour + 60 * 60 * 24 * x@day + 60 * 60 * 24 * 365.25 / 12 * x@month + 60 * 60 * 24 * 365.25 * x@year } #' @description #' `seconds_to_period()` create a period that has the maximum number of #' non-zero elements (days, hours, minutes, seconds). This computation is exact #' because it doesn't involve years or months. #' @rdname period_to_seconds #' @export seconds_to_period <- function(x) { span <- as.double(x) remainder <- abs(span) newper <- period(second = rep(0, length(x))) ## slot(newper, "year") <- remainder %/% (3600 * 24 * 365.25) ## remainder <- remainder %% (3600 * 24 * 365.25) slot(newper, "day") <- remainder %/% (3600 * 24) remainder <- remainder %% (3600 * 24) slot(newper, "hour") <- remainder %/% (3600) remainder <- remainder %% (3600) slot(newper, "minute") <- remainder %/% (60) slot(newper, ".Data") <- remainder %% (60) newper * sign(span) } #' @export summary.Period <- function(object, ...) { nas <- is.na(object) object <- object[!nas] persecs <- period_to_seconds(object) qq <- stats::quantile(persecs) qq <- c(qq[1L:3L], mean(persecs), qq[4L:5L]) qq <- seconds_to_period(qq) qq <- as.character(qq) names(qq) <- c("Min.", "1st Qu.", "Median", "Mean", "3rd Qu.", "Max.") if (any(nas)) c(qq, `NA's` = sum(nas)) else qq } #' @export setMethod("Arith", signature(e1 = "Period", e2 = "ANY"), undefined_arithmetic) #' @export setMethod("Arith", signature(e1 = "ANY", e2 = "Period"), undefined_arithmetic) ## duration is.numeric. So we need these explicits here: #' @export setMethod("Arith", signature(e1 = "Duration", e2 = "Period"), undefined_arithmetic) #' @export setMethod("Arith", signature(e1 = "Period", e2 = "Duration"), undefined_arithmetic) #' @export setMethod("Compare", signature(e1 = "Period", e2 = "Period"), function(e1, e2) { callGeneric(period_to_seconds(e1), period_to_seconds(e2)) }) #' @export setMethod("Compare", signature(e1 = "Period", e2 = "character"), function(e1, e2) { callGeneric(e1, as.period(e2)) }) #' @export setMethod("Compare", signature(e1 = "character", e2 = "Period"), function(e1, e2) { callGeneric(as.period(e1), e2) }) #' @export setMethod("Compare", signature(e1 = "Period", e2 = "Duration"), function(e1, e2) { callGeneric(as.duration(e1), e2) }) #' @export setMethod("Compare", signature(e1 = "Duration", e2 = "Period"), function(e1, e2) { callGeneric(e1, as.duration(e2)) }) #' @export setMethod("Compare", signature(e1 = "Period", e2 = "numeric"), function(e1, e2) { callGeneric(as.numeric(e1, "secs"), e2) }) #' @export setMethod("Compare", signature(e1 = "numeric", e2 = "Period"), function(e1, e2) { callGeneric(e1, as.numeric(e2, "secs")) }) #' @export setMethod("Compare", c(e1 = "Period", e2 = "difftime"), function(e1, e2) { callGeneric(as.numeric(e1, units = "secs"), as.numeric(e2, units = "secs")) }) #' @export setMethod("Compare", c(e1 = "difftime", e2 = "Period"), function(e1, e2) { callGeneric(as.numeric(e1, units = "secs"), as.numeric(e2, units = "secs")) }) lubridate/R/difftimes.r0000644000176200001440000001021613201152061014552 0ustar liggesusers#' @include timespans.r #' @include durations.r #' @include intervals.r #' @include periods.r setOldClass("difftime") #' Create a difftime object. #' #' `make_difftime()` creates a difftime object with the specified number of #' units. Entries for different units are cumulative. difftime displays #' durations in various units, but these units are estimates given for #' convenience. The underlying object is always recorded as a fixed number of #' seconds. #' #' Conceptually, difftime objects are a type of duration. They measure the #' exact passage of time but do not always align with measurements #' made in larger units of time such as hours, months and years. #' This is because the length of larger time units can be affected #' by conventions such as leap years #' and Daylight Savings Time. \pkg{lubridate} provides a second class for measuring durations, the Duration class. #' @param num Optional number of seconds #' @param units a character vector that lists the type of units to use for the #' display of the return value (see examples). If `units` is "auto" (the #' default) the display units are computed automatically. This might create #' undesirable effects when converting `difftime` objects to numeric #' values in data processing. #' @param ... a list of time units to be included in the difftime and their amounts. Seconds, #' minutes, hours, days, and weeks are supported. Normally only one of `num` or `...` are present. If #' both are present, the `difftime` objects are concatenated. #' @return a difftime object #' @seealso [duration()], [as.duration()] #' @keywords chron classes #' @export #' @examples #' make_difftime(1) #' make_difftime(60) #' make_difftime(3600) #' make_difftime(3600, units = "minute") #' # Time difference of 60 mins #' make_difftime(second = 90) #' # Time difference of 1.5 mins #' make_difftime(minute = 1.5) #' # Time difference of 1.5 mins #' make_difftime(second = 3, minute = 1.5, hour = 2, day = 6, week = 1) #' # Time difference of 13.08441 days #' make_difftime(hour = 1, minute = -60) #' # Time difference of 0 secs #' make_difftime(day = -1) #' # Time difference of -1 days #' make_difftime(120, day = -1, units = "minute") #' # Time differences in mins make_difftime <- function(num = NULL, units = "auto", ...) { pieces <- list(...) if (!is.null(num) && length(pieces) > 0) { .difftime_from_num(c(num, .difftime_from_pieces(pieces)), units) } else if (!is.null(num)) { .difftime_from_num(num, units) } else if (length(pieces)) { .difftime_from_num(.difftime_from_pieces(pieces), units) } else { stop("No valid values have been passed to 'make_difftime' constructor") } } .difftime_from_num <- function(num, units = "auto") { seconds <- abs(na.omit(num)) if (units == "auto") { if (any(seconds < 60)) units <- "secs" else if (any(seconds < 3600)) units <- "mins" else if (any(seconds < 86400)) units <- "hours" else units <- "days" } units <- standardise_date_names(units[[1]]) switch(units, second = structure(num, units = "secs", class = "difftime"), minute = structure(num/60, units = "mins", class = "difftime"), hour = structure(num/3600, units = "hours", class = "difftime"), day = structure(num/86400, units = "days", class = "difftime"), stop(sprintf("invalid units '%s'. Only 'second', 'minute', 'hour' and 'day' are supported.", units))) } .difftime_from_pieces <- function(pieces) { names(pieces) <- standardise_difftime_names(names(pieces)) defaults <- list(secs = 0, mins = 0, hours = 0, days = 0, weeks = 0) pieces <- c(pieces, defaults[setdiff(names(defaults), names(pieces))]) x <- pieces$secs + pieces$mins * 60 + pieces$hours * 3600 + pieces$days * 86400 + pieces$weeks * 604800 x } #' Is x a difftime object? #' #' @export is.difftime #' @param x an R object #' @return TRUE if x is a difftime object, FALSE otherwise. #' @seealso [is.instant()], [is.timespan()], [is.interval()], #' [is.period()]. #' @keywords logic chron #' @examples #' is.difftime(as.Date("2009-08-03")) # FALSE #' is.difftime(make_difftime(days = 12.4)) # TRUE is.difftime <- function(x) is(x, "difftime") lubridate/R/ops-m+.r0000644000176200001440000001400713201152061013710 0ustar liggesusers#' @include timespans.r #' @include durations.r #' @include intervals.r #' @include periods.r #' @include Dates.r #' @include difftimes.r #' @include numeric.r #' @include POSIXt.r #' @include ops-addition.r NULL #' Add and subtract months to a date without exceeding the last day of the new month #' #' Adding months frustrates basic arithmetic because consecutive months have #' different lengths. With other elements, it is helpful for arithmetic to #' perform automatic roll over. For example, 12:00:00 + 61 seconds becomes #' 12:01:01. However, people often prefer that this behavior NOT occur with #' months. For example, we sometimes want January 31 + 1 month = February 28 and #' not March 3. \code{\%m+\%} performs this type of arithmetic. Date \code{\%m+\%} months(n) #' always returns a date in the nth month after Date. If the new date would #' usually spill over into the n + 1th month, \code{\%m+\%} will return the last day of #' the nth month ([rollback()]). Date \code{\%m-\%} months(n) always returns a #' date in the nth month before Date. #' #' \code{\%m+\%} and \code{\%m-\%} handle periods with components less than a month by first #' adding/substracting months and then performing usual arithmetics with smaller #' units. #' #' \code{\%m+\%} and \code{\%m-\%} should be used with caution as they are not one-to-one #' operations and results for either will be sensitive to the order of #' operations. #' #' @rdname mplus #' @usage e1 \%m+\% e2 #' @aliases m+ %m+% m- %m-% %m+%,ANY,ANY-method %m-%,ANY,ANY-method %m+%,Period,ANY-method %m+%,ANY,Period-method %m-%,Period,ANY-method %m-%,ANY,Period-method %m+%,Duration,ANY-method %m+%,ANY,Duration-method %m-%,Duration,ANY-method %m-%,ANY,Duration-method %m+%,Interval,ANY-method %m+%,ANY,Interval-method %m-%,Interval,ANY-method %m-%,ANY,Interval-method #' @param e1 A period or a date-time object of class [POSIXlt], [POSIXct] #' or [Date]. #' @param e2 A period or a date-time object of class [POSIXlt], [POSIXct] #' or [Date]. Note that one of e1 and e2 must be a period and the other a #' date-time object. #' @return A date-time object of class POSIXlt, POSIXct or Date #' @examples #' jan <- ymd_hms("2010-01-31 03:04:05") #' jan + months(1:3) # Feb 31 and April 31 returned as NA #' # NA "2010-03-31 03:04:05 UTC" NA #' jan %m+% months(1:3) # No rollover #' #' leap <- ymd("2012-02-29") #' "2012-02-29 UTC" #' leap %m+% years(1) #' leap %m+% years(-1) #' leap %m-% years(1) #' @export "%m+%" <- function(e1, e2) standardGeneric("%m+%") #' @export setGeneric("%m+%") #' @export setMethod("%m+%", signature(e2 = "Period"), function(e1, e2) add_with_rollback(e1, e2)) #' @export setMethod("%m+%", signature(e1 = "Period"), function(e1, e2) add_with_rollback(e2, e1)) #' @export setMethod("%m+%", signature(e2 = "ANY"), function(e1, e2) stop("%m+% handles only Period objects as second argument")) #' @export "%m-%" <- function(e1, e2) standardGeneric("%m-%") #' @export setGeneric("%m-%") #' @export setMethod("%m-%", signature(e2 = "Period"), function(e1, e2) add_with_rollback(e1, -e2)) #' @export setMethod("%m-%", signature(e1 = "Period"), function(e1, e2) add_with_rollback(e2, -e1)) #' @export setMethod("%m-%", signature(e2 = "ANY"), function(e1, e2) stop("%m-% handles only Period objects as second argument")) #' `add_with_rollback()` provides additional functionality to \code{\%m+\%} and #' \code{\%m-\%}. It allows rollback to first day of the month instead of the last day #' of the previous month and controls whether HMS component of the end date is #' preserved or not. #' @rdname mplus #' @param roll_to_first rollback to the first day of the month instead of the #' last day of the previous month (passed to [rollback()]) #' @param preserve_hms retains the same hour, minute, and second information? If #' FALSE, the new date will be at 00:00:00 (passed to [rollback()]) #' @export add_with_rollback <- function(e1, e2, roll_to_first = FALSE, preserve_hms = TRUE) { any_HMS <- any(e2@.Data != 0) || any(e2@minute != 0) || any(e2@hour != 0) || any(e2@day != 0) any_year <- any(e2@year != 0) if (!is.na(any_year) && any_year) { e2$month <- 12 * e2@year + e2@month e2$year <- 0L } new <- .quick_month_add(e1, e2@month) roll <- day(new) < day(e1) roll <- !is.na(roll) & roll new[roll] <- rollback(new[roll], roll_to_first = roll_to_first, preserve_hms = preserve_hms) if (!is.na(any_HMS) && any_HMS) { e2$month <- 0L new + e2 } else { new } } .quick_month_add <- function(object, mval) { tzs <- tz(object) utc <- as.POSIXlt(force_tz(object, tzone = "UTC")) utc$mon <- utc$mon + mval utc <- as.POSIXct(utc) new <- force_tz(utc, tzone = tzs) reclass_date(new, object) } #' Roll back date to last day of previous month #' #' rollback changes a date to the last day of the previous month or to the first #' day of the month. Optionally, the new date can retain the same hour, minute, #' and second information. #' #' @export #' @param dates A POSIXct, POSIXlt or Date class object. #' @param roll_to_first Rollback to the first day of the month instead of the #' last day of the previous month #' @param preserve_hms Retains the same hour, minute, and second information? If #' FALSE, the new date will be at 00:00:00. #' @return A date-time object of class POSIXlt, POSIXct or Date, whose day has #' been adjusted to the last day of the previous month, or to the first day of #' the month. #' @examples #' date <- ymd("2010-03-03") #' rollback(date) #' #' dates <- date + months(0:2) #' rollback(dates) #' #' date <- ymd_hms("2010-03-03 12:44:22") #' rollback(date) #' rollback(date, roll_to_first = TRUE) #' rollback(date, preserve_hms = FALSE) #' rollback(date, roll_to_first = TRUE, preserve_hms = FALSE) rollback <- function(dates, roll_to_first = FALSE, preserve_hms = TRUE) { if (length(dates) == 0) return(dates) day(dates) <- 1 if (!preserve_hms) { hour(dates) <- 0 minute(dates) <- 0 second(dates) <- 0 } if (roll_to_first) { dates } else { dates - days(1) } } lubridate/R/am-pm.r0000644000176200001440000000047313103077700013622 0ustar liggesusers#' Does date time occur in the am or pm? #' #' @export #' @param x a date-time object #' @return TRUE or FALSE depending on whether x occurs in the am or pm #' @keywords chron #' @examples #' x <- ymd("2012-03-26") #' am(x) #' pm(x) am <- function(x) hour(x) < 12 #' @export #' @rdname am pm <- function(x) !am(x) lubridate/R/ops-modulo.r0000644000176200001440000000226013263123374014713 0ustar liggesusers#' @include timespans.r #' @include durations.r #' @include intervals.r #' @include periods.r NULL modulo_duration_by_duration <- function(dur, dur2) dur - dur %/% dur2 * dur2 modulo_interval_by_duration <- function(int, dur) interval(int@start + (int@.Data %/% dur@.Data * dur), int_end(int)) modulo_interval_by_period <- function(int, per) interval(add_with_rollback(int@start, (int %/% per) * per), int_end(int)) modulo_period_by_period <- function(per, per2) per - per %/% per2 * per2 #' @export setMethod("%%", signature(e1 = "Duration", e2 = "Duration"), function(e1, e2) modulo_duration_by_duration(e1, e2)) #' @export setMethod("%%", signature(e1 = "Interval", e2 = "Duration"), function(e1, e2) modulo_interval_by_duration(e1, e2)) #' @export setMethod("%%", signature(e1 = "Interval", e2 = "Interval"), function(e1, e2) stop("%% not defined for Interval class\nConsider setdiff()")) #' @export setMethod("%%", signature(e1 = "Interval", e2 = "Period"), function(e1, e2) modulo_interval_by_period(e1, e2)) #' @export setMethod("%%", signature(e1 = "Period", e2 = "Period"), function(e1, e2) modulo_period_by_period(e1, e2)) lubridate/R/accessors-month.r0000644000176200001440000000737413201152061015723 0ustar liggesusers#' @include periods.r NULL #' Get/set months component of a date-time #' #' Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, #' zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. #' #' @param x a date-time object #' @param label logical. TRUE will display the month as a character string such #' as "January." FALSE will display the month as a number. #' @param abbr logical. FALSE will display the month as a character string #' label, such as "January". TRUE will display an abbreviated version of the #' label, such as "Jan". abbr is disregarded if label = FALSE. #' @param value a numeric object #' @param locale for month, locale to use for month names. Default to current locale. #' @return the months element of x as a number (1-12) or character string. 1 = #' January. #' @keywords utilities manip chron methods #' @examples #' x <- ymd("2012-03-26") #' month(x) #' month(x) <- 1 #' month(x) <- 13 #' month(x) > 3 #' #' month(ymd(080101)) #' month(ymd(080101), label = TRUE) #' month(ymd(080101), label = TRUE, abbr = FALSE) #' month(ymd(080101) + months(0:11), label = TRUE) #' @export month <- function(x, label = FALSE, abbr = TRUE, locale = Sys.getlocale("LC_TIME")) UseMethod("month") #' @export month.default <- function(x, label = FALSE, abbr = TRUE, locale = Sys.getlocale("LC_TIME")) month(as.POSIXlt(x, tz = tz(x))$mon + 1, label, abbr, locale = locale) #' @export month.numeric <- function(x, label = FALSE, abbr = TRUE, locale = Sys.getlocale("LC_TIME")) { if (!label) return(x) names <- .get_locale_regs(locale)$month_names labels <- if (abbr) names$abr else names$full ordered(x, levels = 1:12, labels = labels) } #' @export month.Period <- function(x, label = FALSE, abbr = TRUE, locale = Sys.getlocale("LC_TIME")) slot(x, "month") #' @rdname month #' @export "month<-" <- function(x, value) { ## FIXME: how to make this localized and preserve backward compatibility? Guesser? if (!is.numeric(value)) { value <- pmatch(tolower(value), c("january", "february", "march", "june", "july", "august", "september", "october", "november", "december")) } x <- x + months(value - month(x)) } setGeneric("month<-") #' @export setMethod("month<-", signature("Period"), function(x, value) { slot(x, "month") <- value x }) #' Get the number of days in the month of a date-time #' #' Date-time must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, #' zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. #' #' @export #' @param x a date-time object #' @return An integer of the number of days in the month component of the date-time object. days_in_month <- function(x) { month_x <- month(x, label = TRUE, locale = "C") n_days <- N_DAYS_IN_MONTHS[month_x] n_days[month_x == "Feb" & leap_year(x)] <- 29L n_days } ## fixme: integrate with above, this oen is needed internally .days_in_month <- function(m, y) { n_days <- N_DAYS_IN_MONTHS[m] n_days[m == 2L & leap_year(y)] <- 29L n_days } ## tothink: export? days_in_months_so_far <- function(month, leap) { ## if month is negative, compute from the end of the year cum_days_pos <- c(0, cumsum(N_DAYS_IN_MONTHS)[-12]) cum_days_neg <- c(0, cumsum(rev(N_DAYS_IN_MONTHS))[-12]) negative <- month < 0 positive <- month > 0 sofar <- integer(length(month)) sofar[negative] <- cum_days_neg[-month[negative]] sofar[positive] <- cum_days_pos[month[positive]] adjust <- leap & ((negative & month == -12) | (positive & month > 2)) sofar[adjust] <- sofar[adjust] + 1L sofar } ## days_in_months_so_far(c(1, 2, 3, -10, -11, -12), rep.int(T, 6)) ## [1] 0 31 60 275 306 335 ## days_in_months_so_far(c(1, 2, 3, -10, -11, -12), rep.int(F, 6)) ## [1] 0 31 59 275 306 334 lubridate/R/timespans.r0000644000176200001440000000664113201152061014612 0ustar liggesusers#' Timespan class #' #' Timespan is an S4 class with no slots. It is extended by the #' [Interval-class], [Period-class], and [Duration-class] #' classes. #' #' @export #' @keywords internal #' @aliases *,Timespan,Timespan-method %/%,Timespan,Timespan-method %/%,difftime,Timespan-method setClass("Timespan") #' Is x a length of time? #' #' @export is.timespan #' @aliases is.timespan #' @param x an R object #' @return TRUE if x is a period, interval, duration, or difftime object, FALSE otherwise. #' @seealso [is.instant()], [is.duration()], [is.difftime()], [is.period()], [is.interval()] #' @keywords logic chron #' @examples #' is.timespan(as.Date("2009-08-03")) # FALSE #' is.timespan(duration(second = 1)) # TRUE is.timespan <- function(x) is(x, "Timespan") #' Description of time span classes in lubridate #' #' @description #' A time span can be measured in three ways: as a duration, an interval, or a #' period. #' #' * [duration]s record the exact number of seconds in a time span. #' They measure the exact passage of time but do not always align with #' human measurements like hours, months and years. #' #' * [period]s record the change in the clock time between two date-times. #' They are measured in human units: years, months, days, hours, minutes, #' and seconds. #' #' * [intervals] are time spans bound by two real date-times. Intervals can be #' accurately converted to periods and durations. #' #' @aliases timespans #' @keywords classes chron #' @examples #' duration(3690, "seconds") #' period(3690, "seconds") #' period(second = 30, minute = 1, hour = 1) #' interval(ymd_hms("2009-08-09 13:01:30"), ymd_hms("2009-08-09 12:00:00")) #' #' date <- ymd_hms("2009-03-08 01:59:59") # DST boundary #' date + days(1) #' date + ddays(1) #' #' date2 <- ymd_hms("2000-02-29 12:00:00") #' date2 + years(1) #' # self corrects to next real day #' #' date3 <- ymd_hms("2009-01-31 01:00:00") #' date3 + c(0:11) * months(1) #' #' span <- date2 %--% date #creates interval #' #' date <- ymd_hms("2009-01-01 00:00:00") #' date + years(1) #' date - days(3) + hours(6) #' date + 3 * seconds(10) #' #' months(6) + days(1) #' @name timespan NULL #' Compute the exact length of a time span #' #' #' @param x a duration, period, difftime or interval #' @param unit a character string that specifies with time units to use #' @return the length of the interval in the specified unit. A negative number #' connotes a negative interval or duration #' #' @details When `x` is an [Interval-class] object and #' `unit` are years or months, `time_length()` takes into account #' the fact that all months and years don't have the same number of days. #' #' When `x` is a [Duration-class], [Period-class] #' or [difftime()] object, length in months or years is based on their #' most common lengths in seconds (see [timespan()]). #' @seealso [timespan()] #' @keywords chron math period methods #' @examples #' int <- interval(ymd("1980-01-01"), ymd("2014-09-18")) #' time_length(int, "week") #' #' # Exact age #' time_length(int, "year") #' #' # Age at last anniversary #' trunc(time_length(int, "year")) #' #' # Example of difference between intervals and durations #' int <- interval(ymd("1900-01-01"), ymd("1999-12-31")) #' time_length(int, "year") #' time_length(as.duration(int), "year") #' @export setGeneric("time_length", useAsDefault = function(x, unit = "second") { as.duration(x) / duration(num = 1, units = unit) }) lubridate/R/accessors-date.R0000644000176200001440000000254013201152061015441 0ustar liggesusers#' @include periods.r NULL #' Get/set date component of a date-time #' #' Date-time must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, #' zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. #' #' `date()` does not yet support years before 0 C.E. #' Also `date()` is not defined for Period objects. #' #' @param x a date-time object #' @param value an object for which the `date()` function is defined #' @return the date of x as a Date #' @keywords utilities manip chron methods #' @examples #' x <- ymd_hms("2012-03-26 23:12:13", tz = "America/New_York") #' date(x) #' as.Date(x) # by default as.Date assumes you want to know the date in UTC #' as.Date(x, tz = "America/New_York") #' date(x) <- as.Date("2000-01-02") #' x #' @export date <- function(x) UseMethod("date") #' @export date.default <- function(x) { if (missing(x)) { base::date() } else { x <- as.POSIXlt(x, tz = tz(x)) year <- x$year + 1900 month <- x$mon + 1 day <- x$mday as.Date(make_datetime(year, month, day)) } } #' @export date.Period <- function(x) stop("date is undefined for Period objects") #' @rdname date #' @export "date<-" <- function(x, value) x <- x + days(date(value) - date(x)) setGeneric("date<-") #' @export setMethod("date<-", signature("Period"), function(x, value) { stop("date<- is undefined for Period objects") }) lubridate/R/accessors-quarter.r0000644000176200001440000000250013201152061016243 0ustar liggesusers#' @include accessors-month.r NULL #' Get the fiscal quarter and semester of a date-time #' #' Quarters divide the year into fourths. Semesters divide the year into halfs. #' #' @param x a date-time object of class POSIXct, POSIXlt, Date, chron, yearmon, #' yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, fts or #' anything else that can be converted with as.POSIXlt #' @param with_year logical indicating whether or not to include the quarter's #' year. #' @param fiscal_start numeric indicating the starting month of a fiscal year #' @return numeric #' @examples #' x <- ymd(c("2012-03-26", "2012-05-04", "2012-09-23", "2012-12-31")) #' quarter(x) #' quarter(x, with_year = TRUE) #' quarter(x, with_year = TRUE, fiscal_start = 11) #' semester(x) #' semester(x, with_year = TRUE) #' @export quarter <- function(x, with_year = FALSE, fiscal_start = 1) { fs <- fiscal_start - 1 shifted <- seq(fs, 11 + fs) %% 12 + 1 m <- month(x) quarters <- rep(1:4, each = 3) s <- match(m, shifted) q <- quarters[s] if (with_year) { uq <- quarters[m] inc_year <- q == 1 & uq == 4 year(x) + inc_year + q/10 } else q } #' @rdname quarter #' @export semester <- function(x, with_year = FALSE) { m <- month(x) semesters <- rep(1:2, each = 6) s <- semesters[m] if (with_year) year(x) + s/10 else s } lubridate/R/package.r0000644000176200001440000001600413201152061014174 0ustar liggesusers#' Dates and times made easy with lubridate #' #' Lubridate provides tools that make it easier to parse and #' manipulate dates. These tools are grouped below by common #' purpose. More information about each function can be found in #' its help documentation. #' #' @section Parsing dates: #' #' Lubridate's parsing functions read strings into R as POSIXct #' date-time objects. Users should choose the function whose name #' models the order in which the year ('y'), month ('m') and day #' ('d') elements appear the string to be parsed: #' [dmy()], [myd()], [ymd()], #' [ydm()], [dym()], [mdy()], #' [ymd_hms()]). A very flexible and user friendly parser #' is provided by [parse_date_time()]. #' #' Lubridate can also parse partial dates from strings into #' [Period-class] objects with the functions #' [hm()], [hms()] and [ms()]. #' #' Lubridate has an inbuilt very fast POSIX parser. Most of the [strptime()] #' formats and various extensions are supported for English locales. See #' [parse_date_time()] for more details. #' #' @section Manipulating dates: #' #' Lubridate distinguishes between moments in time (known as #' [instants()]) and spans of time (known as time spans, see #' [Timespan-class]). Time spans are further separated into #' [Duration-class], [Period-class] and #' [Interval-class] objects. #' #' @section Instants: #' #' Instants are specific moments of time. Date, POSIXct, and #' POSIXlt are the three object classes Base R recognizes as #' instants. [is.Date()] tests whether an object #' inherits from the Date class. [is.POSIXt()] tests #' whether an object inherits from the POSIXlt or POSIXct classes. #' [is.instant()] tests whether an object inherits from #' any of the three classes. #' #' [now()] returns the current system time as a POSIXct #' object. [today()] returns the current system date. #' For convenience, 1970-01-01 00:00:00 is saved to #' [origin()]. This is the instant from which POSIXct #' times are calculated. Try unclass(now()) to see the numeric structure that #' underlies POSIXct objects. Each POSIXct object is saved as the number of seconds #' it occurred after 1970-01-01 00:00:00. #' #' Conceptually, instants are a combination of measurements on different units #' (i.e, years, months, days, etc.). The individual values for #' these units can be extracted from an instant and set with the #' accessor functions [second()], [minute()], #' [hour()], [day()], [yday()], #' [mday()], [wday()], [week()], #' [month()], [year()], [tz()], #' and [dst()]. #' Note: the accessor functions are named after the singular form #' of an element. They shouldn't be confused with the period #' helper functions that have the plural form of the units as a #' name (e.g, [seconds()]). #' #' @section Rounding dates: #' #' Instants can be rounded to a convenient unit using the #' functions [ceiling_date()], [floor_date()] #' and [round_date()]. #' #' @section Time zones: #' #' Lubridate provides two helper functions for working with time #' zones. [with_tz()] changes the time zone in which an #' instant is displayed. The clock time displayed for the instant #' changes, but the moment of time described remains the same. #' [force_tz()] changes only the time zone element of an #' instant. The clock time displayed remains the same, but the #' resulting instant describes a new moment of time. #' #' @section Timespans: #' #' A timespan is a length of time that may or may not be connected to #' a particular instant. For example, three months is a timespan. So is an hour and #' a half. Base R uses difftime class objects to record timespans. #' However, people are not always consistent in how they expect time to behave. #' Sometimes the passage of time is a monotone progression of instants that should #' be as mathematically reliable as the number line. On other occasions time must #' follow complex conventions and rules so that the clock times we see reflect what #' we expect to observe in terms of daylight, season, and congruence with the #' atomic clock. To better navigate the nuances of time, \pkg{lubridate} creates three #' additional timespan classes, each with its own specific and consistent behavior: #' [Interval-class], [Period-class] and #' [Duration-class]. #' #' [is.difftime()] tests whether an object #' inherits from the difftime class. [is.timespan()] #' tests whether an object inherits from any of the four timespan #' classes. #' #' @section Durations: #' #' Durations measure the exact amount of time that occurs between two #' instants. This can create unexpected results in relation to clock times if a #' leap second, leap year, or change in daylight savings time (DST) occurs in #' the interval. #' #' Functions for working with durations include [is.duration()], #' [as.duration()] and [duration()]. [dseconds()], #' [dminutes()], [dhours()], [ddays()], #' [dweeks()] and [dyears()] convenient lengths. #' #' @section Periods: #' #' Periods measure the change in clock time that occurs between two #' instants. Periods provide robust predictions of clock time in the presence of #' leap seconds, leap years, and changes in DST. #' #' Functions for working with periods include #' [is.period()], [as.period()] and #' [period()]. [seconds()], #' [minutes()], [hours()], [days()], #' [weeks()], [months()] and #' [years()] quickly create periods of convenient #' lengths. #' #' @section Intervals: #' #' Intervals are timespans that begin at a specific instant and #' end at a specific instant. Intervals retain complete information about a #' timespan. They provide the only reliable way to convert between #' periods and durations. #' #' Functions for working with intervals include #' [is.interval()], [as.interval()], #' [interval()], [int_shift()], #' [int_flip()], [int_aligns()], #' [int_overlaps()], and #' \code{\link{\%within\%}}. Intervals can also be manipulated with #' intersect, union, and setdiff(). #' #' @section Miscellaneous: #' #' [decimal_date()] converts an instant to a decimal of #' its year. #' [leap_year()] tests whether an instant occurs during #' a leap year. #' [pretty_dates()] provides a method of making pretty #' breaks for date-times #' [lakers] is a data set that contains information #' about the Los Angeles Lakers 2008-2009 basketball season. #' #' @references Garrett Grolemund, Hadley Wickham (2011). Dates and Times Made #' Easy with lubridate. Journal of Statistical Software, 40(3), 1-25. #' \url{http://www.jstatsoft.org/v40/i03/}. #' @import stringr #' @importFrom methods setClass setGeneric new show allNames callGeneric is slot slot<- slotNames validObject Compare Arith initialize coerce<- #' @importFrom utils packageVersion read.delim #' @importFrom stats na.omit setNames update #' @importFrom Rcpp sourceCpp #' @useDynLib lubridate, .registration=TRUE #' @keywords internal "_PACKAGE" ## NOTE ON EXPORTS: `useDynLib` from above exports all registered functions (see ## ../src/RcppExports.cpp). _lubridate_C_xyz in there are Rcpp functions. All ## other `C_xyz` functions, are from plain .C files and are added manually with ## the help of tools::package_native_routine_registration_skeleton(".", character_only = FALSE). lubridate/R/ops-integer-division.r0000644000176200001440000000053013201152061016654 0ustar liggesusers#' @include timespans.r NULL integer_divide_spans <- function(e1, e2) { trunc(e1/e2) } #' @export setMethod("%/%", signature(e1 = "Timespan", e2 = "Timespan"), function(e1, e2) integer_divide_spans(e1, e2)) #' @export setMethod("%/%", signature(e1 = "difftime", e2 = "Timespan"), function(e1, e2) integer_divide_spans(e1, e2)) lubridate/R/POSIXt.r0000644000176200001440000000177613263101746013715 0ustar liggesuserssetOldClass("POSIXt") setOldClass("POSIXct") setOldClass("POSIXlt") #' Is x a POSIXct or POSIXlt object? #' #' @export #' @param x an R object #' @return TRUE if x is a POSIXct or POSIXlt object, FALSE otherwise. #' @seealso [is.instant()], [is.timespan()], [is.Date()] #' @keywords logic chron #' @examples #' is.POSIXt(as.Date("2009-08-03")) # FALSE #' is.POSIXt(as.POSIXct("2009-08-03")) # TRUE is.POSIXt <- function(x) inherits(x, "POSIXt") #' @rdname is.POSIXt #' @export is.POSIXlt <- function(x) inherits(x, "POSIXlt") #' @rdname is.POSIXt #' @export is.POSIXct <- function(x) inherits(x, "POSIXct") #' @method c POSIXct c.POSIXct <- function(..., recursive = FALSE) { dots <- list(...) .POSIXct(c(unlist(lapply(dots, unclass))), tz = tz(dots[[1]])) } #' @method c POSIXlt c.POSIXlt <- function(..., recursive = FALSE) { as.POSIXlt(do.call("c.POSIXct", lapply(list(...), as.POSIXct))) } evalqOnLoad({ registerS3method("c", "POSIXct", c.POSIXct) ## registerS3method("c", "POSIXlt", c.POSIXlt) }) lubridate/R/accessors-dst.r0000644000176200001440000000124613201152061015360 0ustar liggesusers#' Get **d**aylight **s**avings **t**ime indicator of a date-time #' #' Date-time must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, #' zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. #' #' A date-time's daylight savings flag can not be set because it depends on the #' date-time's year, month, day, and hour values. #' #' @export #' @param x a date-time object #' @return A logical. TRUE if DST is in force, FALSE if not, NA if unknown. #' @keywords utilities chron methods #' @examples #' x <- ymd("2012-03-26") #' dst(x) dst <- function(x) UseMethod("dst") #' @export dst.default <- function(x) c(NA, FALSE, TRUE)[as.POSIXlt(x)$isdst + 2] lubridate/R/constants.r0000644000176200001440000001062613234704705014637 0ustar liggesusers### Various Constants N_DAYS_IN_MONTHS <- c( Jan = 31L, Feb = 28L, Mar = 31L, Apr = 30L, May = 31L, Jun = 30L, Jul = 31L, Aug = 31L, Sep = 30L, Oct = 31L, Nov = 30L, Dec = 31L) ## lower bound included, upper excluded N_DAYS_BETWEEN_MONTHS_LOWER <- matrix(0L, 12, 12) for (i in 1:12) for (j in 1:12) { N_DAYS_BETWEEN_MONTHS_LOWER[[i, j]] <- if (i < j) sum(N_DAYS_IN_MONTHS[i:(j - 1)]) else if (j < i) sum(N_DAYS_IN_MONTHS[-(j:(i - 1))]) else 0L } ## upper bound included, lower excluded N_DAYS_BETWEEN_MONTHS_UPPER <- matrix(0L, 12, 12) for (i in 1:12) for (j in 1:12) { N_DAYS_BETWEEN_MONTHS_UPPER[[i, j]] <- if (i < j) sum(N_DAYS_IN_MONTHS[(i + 1):j]) else if (j < i) sum(N_DAYS_IN_MONTHS[-((j + 1):i)]) else 0L } lub2base_units <- list(second = "secs", minute = "mins", hour = "hours", day = "days") ### Used in guess.R ## dput(as.POSIXct(sprintf("1970-%02d-%02d %s:00:00", 1:12, c(1, 2, 3, 5), c("01", "22")), tz = "UTC")) .date_template <- structure(c(3600, 2844000, 5274000, 8200800, 10371600, 13212000, 15814800, 18741600, 20998800, 23752800, 26442000, 29282400), class = c("POSIXct", "POSIXt"), tzone = "UTC") .primes <- c(1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, 3547, 3557, 3559, 3571) lubridate/R/accessors-second.r0000644000176200001440000000165413201152061016044 0ustar liggesusers#' @include periods.r NULL #' Get/set seconds component of a date-time #' #' Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, #' zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. #' #' @export #' @param x a date-time object #' @return the seconds element of x as a decimal number #' @keywords utilities manip chron methods #' @examples #' x <- ymd("2012-03-26") #' second(x) #' second(x) <- 1 #' second(x) <- 61 #' second(x) > 2 second <- function(x) UseMethod("second") #' @export second.default <- function(x) as.POSIXlt(x, tz = tz(x))$sec #' @export second.Period <- function(x) slot(x, ".Data") #' @rdname second #' @param value numeric value to be assigned #' @export "second<-" <- function(x, value) x <- x + seconds(value - second(x)) setGeneric("second<-") #' @export setMethod("second<-", signature("Period"), function(x, value) { slot(x, ".Data") <- value x }) lubridate/R/ops-multiplication.r0000644000176200001440000000247713201152061016446 0ustar liggesusers#' @include timespans.r #' @include durations.r #' @include intervals.r #' @include periods.r NULL multiply_duration_by_number <- function(dur, num) new("Duration", dur@.Data * num) multiply_interval_by_number <- function(int, num) { new("Interval", int@.Data * num, start = int@start, tzone = int@tzone) } multiply_period_by_number <- function(per, num) { new("Period", per@.Data * num, year = per@year * num, month = per@month * num, day = per@day * num, hour = per@hour * num, minute = per@minute * num) } #' @export setMethod("*", signature(e1 = "Timespan", e2 = "Timespan"), function(e1, e2) stop("cannot multiply time span by time span")) #' @export setMethod("*", signature(e1 = "Duration"), function(e1, e2) multiply_duration_by_number(e1, e2)) #' @export setMethod("*", signature(e2 = "Duration"), function(e1, e2) multiply_duration_by_number(e2, e1)) #' @export setMethod("*", signature(e1 = "Interval"), function(e1, e2) multiply_interval_by_number(e1, e2)) #' @export setMethod("*", signature(e2 = "Interval"), function(e1, e2) multiply_interval_by_number(e2, e1)) #' @export setMethod("*", signature(e1 = "Period"), function(e1, e2) multiply_period_by_number(e1, e2)) #' @export setMethod("*", signature(e2 = "Period"), function(e1, e2) multiply_period_by_number(e2, e1)) lubridate/R/accessors-day.r0000644000176200001440000001110613234604040015344 0ustar liggesusers#' @include periods.r NULL #' Get/set days component of a date-time #' #' @details `day()` and `day<-()` are aliases for `mday()` and `mday<-()` #' respectively. #' @param x a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, #' timeDate, xts, its, ti, jul, timeSeries, or fts object. #' @param label logical. Only available for wday. TRUE will display the day of #' the week as an ordered factor of character strings, such as "Sunday." FALSE #' will display the day of the week as a number. #' @param abbr logical. Only available for wday. FALSE will display the day of #' the week as an ordered factor of character strings, such as "Sunday." TRUE #' will display an abbreviated version of the label, such as "Sun". abbr is #' disregarded if label = FALSE. #' @param value a numeric object #' @param week_start day on which week starts following ISO conventions - 1 #' means Monday, 7 means Sunday (default). You can set `lubridate.week.start` #' option to control this parameter globally. #' @param locale locale to use for day names. Default to current locale. #' @return `wday()` returns the day of the week as a decimal number or an #' ordered factor if label is `TRUE`. #' @seealso [yday()], [mday()] #' @keywords utilities manip chron methods #' @examples #' x <- as.Date("2009-09-02") #' wday(x) #4 #' #' wday(ymd(080101)) #' wday(ymd(080101), label = TRUE, abbr = FALSE) #' wday(ymd(080101), label = TRUE, abbr = TRUE) #' wday(ymd(080101) + days(-2:4), label = TRUE, abbr = TRUE) #' #' x <- as.Date("2009-09-02") #' yday(x) #245 #' mday(x) #2 #' yday(x) <- 1 #"2009-01-01" #' yday(x) <- 366 #"2010-01-01" #' mday(x) > 3 #' @export day mday day <- function(x) UseMethod("mday") #' @rdname day #' @export mday <- day #' @rdname day #' @export wday <- function(x, label = FALSE, abbr = TRUE, week_start = getOption("lubridate.week.start", 7), locale = Sys.getlocale("LC_TIME")) UseMethod("wday") #' @export wday.default <- function(x, label = FALSE, abbr = TRUE, week_start = getOption("lubridate.week.start", 7), locale = Sys.getlocale("LC_TIME")) { wday(as.POSIXlt(x, tz = tz(x))$wday + 1, label, abbr, locale = locale, week_start = week_start) } .shift_wday_names <- function(names, week_start = 7) { if (week_start != 7) { c(names[(week_start + 1):7], names[1:week_start]) } else { names } } #' @export wday.numeric <- function(x, label = FALSE, abbr = TRUE, week_start = getOption("lubridate.week.start", 7), locale = Sys.getlocale("LC_TIME")) { start <- as.integer(week_start) if (start > 7 || start < 1) stop("Invalid 'week_start' argument; must be between 1 and 7") if (start != 7) { x <- 1 + (x + (6 - start)) %% 7 } if (!label) { return(x) } names <- .get_locale_regs(locale)$wday_names labels <- if (abbr) names$abr else names$full ordered(x, levels = 1:7, labels = .shift_wday_names(labels, week_start = start)) } #' @export mday.default <- function(x) as.POSIXlt(x, tz = tz(x))$mday #' @export mday.Period <- function(x) slot(x, "day") #' @rdname day #' @export qday <- function(x) UseMethod("qday") #' @export qday.default <- function(x) { x <- as_date(x) as.integer(x - floor_date(x, "quarter")) + 1 } #' @rdname day #' @export yday <- function(x) UseMethod("yday") #' @export yday.default <- function(x) as.POSIXlt(x, tz = tz(x))$yday + 1 #' @rdname day #' @export `day<-` <- function(x, value) standardGeneric("day<-") #' @rdname day #' @export `mday<-` <- function(x, value) { day(x) <- value x } #' @rdname day #' @export `qday<-` <- function(x, value) standardGeneric("qday<-") #' @export setGeneric("qday<-", useAsDefault = function(x, value) x <- x + days(value - qday(x))) #' @export setGeneric("day<-", useAsDefault = function(x, value) x <- x + days(value - mday(x))) #' @export setMethod("day<-", signature("Period"), function(x, value) { slot(x, "day") <- value x }) #' @rdname day #' @export "wday<-" <- function(x, week_start = getOption("lubridate.week.start", 7), value) { if (!is.numeric(value)) { ## FIXME: how to make this localized and preserve backward compatibility? Guesser? labels <- .shift_wday_names(c("sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"), week_start) value <- pmatch(tolower(value), labels) } x <- x + days(value - wday(x, week_start = week_start)) } #' @rdname day #' @export "yday<-" <- function(x, value) x <- x + days(value - yday(x)) lubridate/R/accessors-hour.r0000644000176200001440000000164313201152061015544 0ustar liggesusers#' @include periods.r NULL #' Get/set hours component of a date-time #' #' Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, #' zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. #' #' @export #' @param x a date-time object #' @keywords utilities manip chron methods #' @return the hours element of x as a decimal number #' @examples #' x <- ymd("2012-03-26") #' hour(x) #' hour(x) <- 1 #' hour(x) <- 25 #' hour(x) > 2 hour <- function(x) UseMethod("hour") #' @export hour.default <- function(x) as.POSIXlt(x, tz = tz(x))$hour #' @export hour.Period <- function(x) slot(x, "hour") #' @export #' @param value numeric value to be assigned to the `hour` component #' @rdname hour "hour<-" <- function(x, value) x <- x + hours(value - hour(x)) setGeneric("hour<-") #' @export setMethod("hour<-", signature("Period"), function(x, value) { slot(x, "hour") <- value x }) lubridate/R/durations.r0000644000176200001440000003112113234630403014615 0ustar liggesusers#' @include timespans.r #' @include difftimes.r check_duration <- function(object) { if (is.numeric(object@.Data)) TRUE else "Duration value is not a number. Should be numeric." } #' Duration class #' #' Duration is an S4 class that extends the [Timespan-class] class. #' Durations record the exact number of seconds in a time span. They measure the #' exact passage of time but do not always align with measurements #' made in larger units of time such as hours, months and years. #' This is because the exact length of larger time units can be affected #' by conventions such as leap years #' and Daylight Savings Time. #' #' Durations provide a method for measuring generalized timespans when we wish to #' treat time as a mathematical quantity that increases in a uniform, monotone manner #' along a continuous numberline. They allow exact comparisons with other durations. #' See [Period-class] for an alternative way to measure timespans that better #' preserves clock times. #' #' Durations class objects have one slot: .Data, a numeric object equal to the number #' of seconds in the duration. #' #' @aliases durations #' @export setClass("Duration", contains = c("Timespan", "numeric"), validity = check_duration) #' @name hidden_aliases #' @aliases Compare,Duration,ANY-method Compare,Duration,Duration-method #' Compare,difftime,Duration-method Compare,ANY,Duration-method #' Compare,Duration,Period-method Compare,Duration,difftime-method #' Compare,character,Duration-method Compare,Duration,character-method #' as.numeric,Duration-method show,Duration-method c,Duration-method #' rep,Duration-method [,Duration-method [<-,Duration,ANY,ANY,ANY-method #' [[,Duration-method [[<-,Duration,ANY,ANY,ANY-method $,Duration-method #' $<-,Duration-method as.difftime,Duration-method #' as.character,Duration-method +,Duration,Duration-method #' +,Duration,Interval-method +,Duration,Period-method +,Duration,Date-method #' +,Date,Duration-method +,Duration,difftime-method #' +,difftime,Duration-method +,Duration,numeric-method #' +,numeric,Duration-method +,Duration,POSIXct-method #' +,POSIXct,Duration-method +,Duration,POSIXlt-method #' +,POSIXlt,Duration-method -,Duration,ANY-method /,Duration,Duration-method #' /,Duration,Interval-method /,Duration,Period-method #' /,Duration,difftime-method /,difftime,Duration-method #' /,Duration,numeric-method /,numeric,Duration-method *,Duration,ANY-method #' *,ANY,Duration-method %%,Duration,Duration-method #' %%,Duration,Interval-method %%,Duration,Period-method #' -,Duration,missing-method -,ANY,Duration-method NULL SECONDS_IN_ONE <- c( second = 1, minute = 60, hour = 3600, day = 86400, week = 604800, year = 31557600) .readable_duration <- function(x, unit) { if (unit == "second") paste0(x, "s") else { x2 <- round(x / SECONDS_IN_ONE[[unit]], 2) sprintf("%ss (~%s %ss)", x, x2, unit) } } .next_unit <- structure(as.list(c(names(SECONDS_IN_ONE[-1]), list(NULL))), names = names(SECONDS_IN_ONE)) compute_estimate <- function (secs, unit = "second") { next_unit <- .next_unit[[unit]] if (is.null(next_unit)) return(.readable_duration(secs, "year")) out <- character(length(secs)) tt <- secs < SECONDS_IN_ONE[[next_unit]] if (any(tt)) out[tt] <- .readable_duration(secs[tt], unit) wnext <- which(!tt) out[wnext] <- compute_estimate(secs[wnext], next_unit) out } #' @export setMethod("show", signature(object = "Duration"), function(object) { print(format.Duration(object), quote = TRUE) }) #' @export format.Duration <- function(x, ...) { if (length(x@.Data) == 0) return("Duration(0)") out <- vector("character", length(x@.Data)) nnas <- !is.na(x@.Data) out[nnas] <- compute_estimate(abs(x@.Data[nnas])) out[!nnas] <- NA out } #' @export setMethod("c", signature(x = "Duration"), function(x, ...) { durs <- c(x@.Data, unlist(list(...))) new("Duration", durs) }) #' @export setMethod("rep", signature(x = "Duration"), function(x, ...) { new("Duration", rep(as.numeric(x), ...)) }) #' @export setMethod("[", signature(x = "Duration"), function(x, i, j, ..., drop = TRUE) { new("Duration", x@.Data[i]) }) #' @export setMethod("[[", signature(x = "Duration"), function(x, i, j, ..., exact = TRUE) { new("Duration", x@.Data[i]) }) #' @export setMethod("[<-", signature(x = "Duration"), function(x, i, j, ..., value) { x@.Data[i] <- value new("Duration", x@.Data) }) #' @export setMethod("[[<-", signature(x = "Duration"), function(x, i, j, ..., value) { x@.Data[i] <- as.numeric(value) new("Duration", x@.Data) }) #' Create a duration object. #' #' `duration()` creates a duration object with the specified values. Entries #' for different units are cumulative. durations display as the number of #' seconds in a time span. When this number is large, durations also display an #' estimate in larger units,; however, the underlying object is always recorded #' as a fixed number of seconds. For display and creation purposes, units are #' converted to seconds using their most common lengths in seconds. Minutes = 60 #' seconds, hours = 3600 seconds, days = 86400 seconds, weeks = 604800. Units #' larger than weeks are not used due to their variability. #' #' Durations record the exact number of seconds in a time span. They measure the #' exact passage of time but do not always align with measurements #' made in larger units of time such as hours, months and years. #' This is because the length of larger time units can be affected #' by conventions such as leap years #' and Daylight Savings Time. Base R provides a second class for measuring #' durations, the difftime class. #' #' Duration objects can be easily created with the helper functions [dweeks()], #' [ddays()], [dminutes()], [dseconds()]. These objects can be added to and #' subtracted to date- times to create a user interface similar to object #' oriented programming. #' #' @param num the number or a character vector of time units. In string #' representation all unambiguous name units and abbreviations and ISO 8601 #' formats are supported; 'm' stands for month and 'M' for minutes unless ISO #' 8601 "P" modifier is present (see examples). Fractional units are #' supported. #' @param units a character string that specifies the type of units that num #' refers to. When `num` is character, this argument is ignored. #' @param ... a list of time units to be included in the duration and their #' amounts. Seconds, minutes, hours, days, and weeks are supported. #' @param x numeric value of the number of units to be contained in the #' duration. #' @return a duration object #' @seealso [as.duration()] [Duration-class] #' @keywords chron classes #' @examples #' #' ### Separate period and units vectors #' #' duration(90, "seconds") #' duration(1.5, "minutes") #' duration(-1, "days") #' #' ### Units as arguments #' #' duration(day = -1) #' duration(second = 90) #' duration(minute = 1.5) #' duration(mins = 1.5) #' duration(second = 3, minute = 1.5, hour = 2, day = 6, week = 1) #' duration(hour = 1, minute = -60) #' #' ### Parsing #' #' duration("2M 1sec") #' duration("2hours 2minutes 1second") #' duration("2d 2H 2M 2S") #' duration("2days 2hours 2mins 2secs") #' # Missing numerals default to 1. Repeated units are added up. #' duration("day day") #' #' ### ISO 8601 parsing #' #' duration("P3Y6M4DT12H30M5S") #' duration("P23DT23H") # M stands for months #' duration("10DT10M") # M stands for minutes #' duration("P23DT60H 20min 100 sec") # mixing ISO and lubridate style parsing #' #' # Comparison with characters (from v1.6.0) #' #' duration("day 2 sec") > "day 1sec" #' #' #' ## ELEMENTARY CONSTRUCTORS: #' #' dseconds(1) #' dminutes(3.5) #' #' x <- ymd_hms("2009-08-03", tz="America/Chicago") #' x + ddays(1) + dhours(6) + dminutes(30) #' x + ddays(100) - dhours(8) #' #' class(as.Date("2009-08-09") + ddays(1)) # retains Date class #' as.Date("2009-08-09") + dhours(12) #' class(as.Date("2009-08-09") + dhours(12)) #' # converts to POSIXt class to accomodate time units #' #' dweeks(1) - ddays(7) #' c(1:3) * dhours(1) #' #' # compare DST handling to durations #' boundary <- ymd_hms("2009-03-08 01:59:59", tz="America/Chicago") #' boundary + days(1) # period #' boundary + ddays(1) # duration #' @export duration <- function(num = NULL, units = "seconds", ...) { nums <- list(...) if (is.character(num)) { as.duration(parse_period(num)) } else if (!is.null(num) && length(nums) > 0) { c(.duration_from_num(num, units), .duration_from_units(nums)) } else if (!is.null(num)) { .duration_from_num(num, units) } else if (length(nums)) { .duration_from_units(nums) } else { stop("No valid values have been passed to 'duration' constructor") } } .duration_from_num <- function(num, units) { if (!is.numeric(num)) { stop(sprintf("First argument to `duration` constructor must be character or numeric. Supplied object of class '%s'", class(num))) } ## qucik check for common wrongdoings: https://github.com/hadley/lubridate/issues/462 if (class(num)[[1]] %in% c("Interval", "Period")) stop("Interval or Period objects cannot be used as input to 'period' constructor. Plese use 'as.duration'.") unit <- standardise_date_names(units) mult <- c(second = 1, minute = 60, hour = 3600, mday = 86400, wday = 86400, yday = 86400, day = 86400, week = 604800, month = 60 * 60 * 24 * 365 / 12, year = 60 * 60 * 24 * 365) new("Duration", num * unname(mult[unit])) } .duration_from_units <- function(pieces) { names(pieces) <- standardise_difftime_names(names(pieces)) defaults <- list(secs = 0, mins = 0, hours = 0, days = 0, weeks = 0) pieces <- c(pieces, defaults[setdiff(names(defaults), names(pieces))]) x <- pieces$secs + pieces$mins * 60 + pieces$hours * 3600 + pieces$days * 86400 + pieces$weeks * 604800 new("Duration", x) } #' @export dseconds dminutes dhours ddays dweeks dyears dmilliseconds dmicroseconds dnanoseconds dpicoseconds #' @rdname duration dseconds <- function(x = 1) new("Duration", x) #' @rdname duration dminutes <- function(x = 1) new("Duration", x * 60) #' @rdname duration dhours <- function(x = 1) new("Duration", x * 3600) #' @rdname duration ddays <- function(x = 1) new("Duration", x * 86400) #' @rdname duration dweeks <- function(x = 1) new("Duration", x * 604800) #' @rdname duration dyears <- function(x = 1) new("Duration", x * 60 * 60 * 24 * 365) #' @rdname duration dmilliseconds <- function(x = 1) new("Duration", x / 1000) #' @rdname duration dmicroseconds <- function(x = 1) new("Duration", x / 1000 / 1000) #' @rdname duration dnanoseconds <- function(x = 1) new("Duration", x / 1000 / 1000 / 1000) #' @rdname duration dpicoseconds <- function(x = 1) new("Duration", x / 1000 / 1000 / 1000 / 1000) #' @rdname duration #' @export #' @examples #' is.duration(as.Date("2009-08-03")) # FALSE #' is.duration(duration(days = 12.4)) # TRUE is.duration <- function(x) is(x, "Duration") #' @export summary.Duration <- function(object, ...) { nas <- is.na(object) object <- object[!nas] nums <- as.numeric(object) qq <- stats::quantile(nums) qq <- c(qq[1L:3L], mean(nums), qq[4L:5L]) qq <- dseconds(qq) qq <- as.character(qq) names(qq) <- c("Min.", "1st Qu.", "Median", "Mean", "3rd Qu.", "Max.") if (any(nas)) c(qq, `NA's` = sum(nas)) else qq } #' @export setMethod("Compare", c(e1 = "Duration", e2 = "ANY"), function(e1, e2) { stop(sprintf("Incompatible duration classes (%s, %s). Please coerce with `as.duration`.", class(e1), class(e2)), call. = FALSE) }) #' @export setMethod("Compare", c(e1 = "ANY", e2 = "Duration"), function(e1, e2) { stop(sprintf("Incompatible duration classes (%s, %s). Please coerce with `as.duration`.", class(e1), class(e2)), call. = FALSE) }) #' @export setMethod("Compare", signature(e1 = "Duration", e2 = "character"), function(e1, e2) { callGeneric(e1, as.duration(e2)) }) #' @export setMethod("Compare", signature(e1 = "character", e2 = "Duration"), function(e1, e2) { callGeneric(as.duration(e1), e2) }) #' @export setMethod("Compare", c(e1 = "difftime", e2 = "Duration"), function(e1, e2) { callGeneric(as.numeric(e1, "secs"), e2@.Data) }) #' @export setMethod("Compare", c(e1 = "Duration", e2 = "difftime"), function(e1, e2) { callGeneric(e1@.Data, as.numeric(e2, "secs")) }) #' @export setMethod("Compare", c(e1 = "Duration", e2 = "Duration"), function(e1, e2) { callGeneric(e1@.Data, e2@.Data) }) lubridate/R/stamp.r0000644000176200001440000001645513234630403013746 0ustar liggesusers##' Format dates and times based on human-friendly templates ##' ##' Stamps are just like [format()], but based on human-frendly ##' templates like "Recorded at 10 am, September 2002" or "Meeting, Sunday May ##' 1, 2000, at 10:20 pm". ##' ##' `stamp()` is a stamping function date-time templates mainly, though it ##' correctly handles all date and time formats as long as they are ##' unambiguous. `stamp_date()`, and `stamp_time()` are the specialized ##' stamps for dates and times (MHS). These function might be useful when the ##' input template is unambiguous and matches both a time and a date format. ##' ##' Lubridate tries it's best to figure our the formats, but often a given ##' format can be interpreted in several ways. One way to deal with the ##' situation is to provide unambiguous formats like 22/05/81 instead of ##' 10/05/81 if you want d/m/y format. Another option is to use a more ##' specialized stamp_date and stamp_time. The core function `stamp()` give ##' priority to longer date-time formats. ##' ##' Another option is to provide a vector of several values as `x` ##' parameter. Then \pkg{lubridate} will choose the format which fits `x` the ##' best. Note that longer formats are preferred. If you have "22:23:00 PM" then ##' "HMSp" format will be given priority to shorter "HMS" order which also fits ##' the supplied string. ##' ##' Finally, you can give desired format order directly as `orders` ##' argument. ##' ##' @param x a character vector of templates. ##' @param orders orders are sequences of formatting characters which might be ##' used for disambiguation. For example "ymd hms", "aym" etc. See ##' [guess_formats()] for a list of available formats. ##' @param locale locale in which `x` is encoded. On Linux-like systems use ##' `locale -a` in the terminal to list available locales. ##' @param quiet whether to output informative messages. ##' @return a function to be applied on a vector of dates ##' @seealso [guess_formats()], [parse_date_time()], [strptime()] ##' @export ##' @examples ##' D <- ymd("2010-04-05") - days(1:5) ##' stamp("March 1, 1999")(D) ##' sf <- stamp("Created on Sunday, Jan 1, 1999 3:34 pm") ##' sf(D) ##' stamp("Jan 01")(D) ##' stamp("Sunday, May 1, 2000", locale = "C")(D) ##' stamp("Sun Aug 5")(D) #=> "Sun Aug 04" "Sat Aug 04" "Fri Aug 04" "Thu Aug 04" "Wed Aug 03" ##' stamp("12/31/99")(D) #=> "06/09/11" ##' stamp("Sunday, May 1, 2000 22:10", locale = "C")(D) ##' stamp("2013-01-01T06:00:00Z")(D) ##' stamp("2013-01-01T00:00:00-06")(D) ##' stamp("2013-01-01T00:00:00-08:00")(force_tz(D, "America/Chicago")) stamp <- function(x, orders = lubridate_formats, locale = Sys.getlocale("LC_TIME"), quiet = FALSE) { fmts <- unique(guess_formats(x, orders, locale)) if (is.null(fmts)) stop("Couldn't guess formats of: ", x) if (length(fmts) == 1L) { FMT <- fmts[[1]] } else { trained <- .train_formats(x, fmts, locale = locale) formats <- .select_formats(trained) FMT <- formats[[1]] if (!quiet && length(trained) > 1) { message("Multiple formats matched: ", paste("\"", names(trained), "\"(", trained, ")", sep = "", collapse = ", ")) } } if (!quiet) message("Using: \"", FMT, "\"") ## format doesn't accept 'locale' argument; need a hard reset reset_local_expr <- quote( { old_lc_time <- Sys.getlocale("LC_TIME") if (old_lc_time != locale) { on.exit(Sys.setlocale("LC_TIME", old_lc_time)) Sys.setlocale("LC_TIME", locale) } }) ## ISO8601 ## %Ou: "2013-04-16T04:59:59Z" ## %Oo: "2013-04-16T04:59:59+01" ## %Oz: "2013-04-16T04:59:59+0100" ## %OO: "2013-04-16T04:59:59+01:00" ## Is a timezone format? if (grepl("%O[oOzu]|%z", FMT)) { ## We need to post-process x in the case of %Oo, %OO and %Oz formats ## because standard %z output format ignores timezone. ## Post-process only when at the end of the string, otherwise don't bother ## and just output with %z format after a conversion to UTC. oOz_end <- str_extract(FMT, "%O[oOz]$") if (is.na(oOz_end)) { FMT <- sub("%O[oOz]", "%z", sub("%Ou", "Z", FMT, fixed = TRUE)) eval(bquote( function(x, locale = .(locale)) { ## %z ignores timezone if (tz(x[[1]]) != "UTC") x <- with_tz(x, tzone = "UTC") .(reset_local_expr) format(x, format = .(FMT)) })) } else { FMT <- sub("%O[oOz]$", "", FMT) eval(bquote( function(x, locale = .(locale)) { .(reset_local_expr) paste0(format(x, format = .(FMT)), .format_offset(x, fmt = .(oOz_end))) })) } } else { ## most common case eval(bquote(function(x, locale = .(locale)) { .(reset_local_expr) format(x, format = .(FMT)) })) } } .format_offset <- function(x, fmt="%Oz") { ## .format_offset ## ## function to format the offset of a time from UTC ## ## This is an internal function, used in conjunction with [stamp()]. ## There are three available formats: ## ## \itemize{ ## \item \code{\%Oo} +01 ## \item \code{\%Oz} +0100 ## \item \code{\%OO} +01:00 ## } ## ## If the \code{\%Oo} format is used for a half-hour timezone, a warning ## is issued, and the format is changed to \code{\%Oz} ## ## @param x POSIXct for which offset-string is sought ## @param fmt string describing format of offset, default: \code{\%Oz} ## ## @return string ## ## "%Oo" +01 ## "%Oz" +0100 ## "%OO" +01:00 ## calulate offset by forcing this time as utc dtm_utc <- force_tz(x, tzone = "UTC") ## the offset is the duration represented by the difference in time offset_duration = as.duration(dtm_utc - x) ## determine sign .sgn <- ifelse(offset_duration >= as.duration(0), "+", "-") ## remove sign offset_duration <- abs(offset_duration) ## determine hour .hr <- floor(offset_duration/dhours(1)) ## determine minutes .min <- floor((offset_duration - dhours(.hr))/dminutes(1)) ## warning if we need minutes, but are using format without minutes if (any(.min > 0) & fmt == "%Oo") { warning("timezone offset-minutes are non-zero - changing format to %Oz") fmt <- "%Oz" } result <- switch( fmt, "%Oo" = sprintf("%s%02d", .sgn, .hr), "%Oz" = sprintf("%s%02d%02d", .sgn, .hr, .min), "%OO" = sprintf("%s%02d:%02d", .sgn, .hr, .min) ) return(result) } ##' @rdname stamp ##' @export stamp_date <- function(x, locale = Sys.getlocale("LC_TIME")) stamp(x, orders = c("ymd", "dmy", "mdy", "ydm", "dym", "myd", "my", "ym", "md", "dm", "m", "d", "y"), locale = locale) ##' @rdname stamp ##' @export stamp_time <- function(x, locale = Sys.getlocale("LC_TIME")) stamp(x, orders = c("hms", "hm", "ms", "h", "m", "s"), locale = locale) lubridate_formats <- local({ xxx <- c("ymd", "ydm", "mdy", "myd", "dmy", "dym") names(xxx) <- xxx out <- character() for (D in xxx) { out[[paste(D, "_hms", sep = "")]] <- paste(xxx[[D]], "T", sep = "") out[[paste(D, "_hm", sep = "")]] <- paste(xxx[[D]], "R", sep = "") out[[paste(D, "_h", sep = "")]] <- paste(xxx[[D]], "r", sep = "") } out <- c(out, xxx, my = "my", ym = "ym", md = "md", dm = "dm", hms = "T", hm = "R", ms = "MS", h = "r", m = "m", y = "y") ## adding ISO8601 out <- c(ymd_hmsz = "ymdTz", out) out }) lubridate/R/accessors-minute.r0000644000176200001440000000165513201152061016073 0ustar liggesusers#' @include periods.r NULL #' Get/set minutes component of a date-time #' #' Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, #' zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. #' #' @export #' @param x a date-time object #' @keywords utilities manip chron methods #' @return the minutes element of x as a decimal number #' @examples #' x <- ymd("2012-03-26") #' minute(x) #' minute(x) <- 1 #' minute(x) <- 61 #' minute(x) > 2 minute <- function(x) UseMethod("minute") #' @export minute.default <- function(x) as.POSIXlt(x, tz = tz(x))$min #' @export minute.Period <- function(x) slot(x, "minute") #' @rdname minute #' @param value numeric value to be assigned #' @export "minute<-" <- function(x, value) x <- x + minutes(value - minute(x)) setGeneric("minute<-") #' @export setMethod("minute<-", signature("Period"), function(x, value) { slot(x, "minute") <- value x }) lubridate/R/Dates.r0000644000176200001440000000056013201152061013641 0ustar liggesuserssetOldClass("Date") #' Is x a Date object? #' #' @export is.Date #' @param x an R object #' @return TRUE if x is a Date object, FALSE otherwise. #' @seealso [is.instant()], [is.timespan()], [is.POSIXt()] #' @keywords logic chron #' @examples #' is.Date(as.Date("2009-08-03")) # TRUE #' is.Date(difftime(now() + 5, now())) # FALSE is.Date <- function(x) is(x, "Date") lubridate/R/coercion.r0000644000176200001440000005610313263151003014411 0ustar liggesusers#' @include timespans.r #' @include durations.r #' @include intervals.r #' @include periods.r #' @include Dates.r #' @include difftimes.r #' @include numeric.r #' @include POSIXt.r #' @include time-zones.r NULL #' Convert a variety of date-time classes to POSIXlt and POSIXct #' @name DateCoercion #' @keywords internal #' NULL #' @export as.POSIXct.fts <- function(x, tz = "", ...) as.POSIXct(zoo::index(x)) #' @export as.POSIXlt.fts <- function(x, tz = "", ...) as.POSIXlt(zoo::index(x)) ## #' @export ## as.POSIXlt.its <- function(x, tz = "", ...) as.POSIXlt(attr(x, "dates")) ## #' @export ## as.POSIXct.its <- function(x, tz = "", ...) as.POSIXct(attr(x, "dates")) #' @export as.POSIXlt.timeSeries <- function(x, tz = "", ...) { as.POSIXlt(timeDate::timeDate(x@positions, zone = x@FinCenter, FinCenter = x@FinCenter)) } #' @export as.POSIXct.timeSeries <- function(x, tz = "", ...) { as.POSIXct(timeDate::timeDate(x@positions, zone = x@FinCenter, FinCenter = x@FinCenter)) } #' @export as.POSIXlt.irts <- function(x, tz = "", ...) as.POSIXlt(x$time) #' @export as.POSIXct.irts <- function(x, tz = "", ...) as.POSIXct(x$time) #' @export as.POSIXlt.xts <- function(x, tz = "", ...) as.POSIXlt(zoo::index(x)) #' @export as.POSIXct.xts <- function(x, tz = "", ...) as.POSIXct(zoo::index(x)) #' @export as.POSIXlt.zoo <- function(x, tz = "", ...) as.POSIXlt(zoo::index(x)) #' @export as.POSIXct.zoo <- function(x, tz = "", ...) as.POSIXct(zoo::index(x)) #' @export as.POSIXlt.tis <- function(x, tz = "", ...) as.Date(x) #' Convenience method to reclass dates post-modification. #' @keywords internal #' #' @export reclass_date <- function(new, orig) UseMethod("reclass_date", orig) #' @export reclass_date.POSIXlt <- function(new, orig) { as.POSIXlt(new) } #' @export reclass_date.POSIXct <- function(new, orig) { as.POSIXct(new) } #' @export reclass_date.chron <- function(new, orig) { chron::as.chron(new) } #' @export reclass_date.timeDate <- function(new, orig) { timeDate::as.timeDate(new) } ## #' @export ## reclass_date.its <- function(new, orig) { ## its::its(new, format = "%Y-%m-%d %X") ## } #' @export reclass_date.ti <- function(new, orig) { tis::as.ti(new, tis::tifName(orig)) } #' @export reclass_date.Date <- function(new, orig) { as.Date(new) } period_to_difftime <- function(per) { as.difftime(per) } #' Convenience method to reclass timespans post-modification. #' @keywords internal #' #' @aliases reclass_timespan,ANY,Duration-method reclass_timespan,ANY,Interval-method #' reclass_timespan,ANY,Period-method reclass_timespan,ANY,difftime-method #' @export reclass_timespan <- function(new, orig) standardGeneric("reclass_timespan") #' @export setGeneric("reclass_timespan") #' @export setMethod("reclass_timespan", signature(orig = "difftime"), function(new, orig) { if (is.period(new)) as.difftime(new) else make_difftime(as.numeric(new)) }) #' @export setMethod("reclass_timespan", signature(orig = "Duration"), function(new, orig) { as.duration(new) }) #' @export setMethod("reclass_timespan", signature(orig = "Interval"), function(new, orig) { as.duration(new) }) #' @export setMethod("reclass_timespan", signature(orig = "Period"), function(new, orig) { as.period(new) }) #' Change an object to a duration #' #' as.duration changes Interval, Period and numeric class objects to #' Duration objects. Numeric objects are changed to Duration objects #' with the seconds unit equal to the numeric value. #' #' Durations are exact time measurements, whereas periods are relative time #' measurements. See [Period-class]. The length of a period depends #' on when it occurs. Hence, a one to one mapping does not exist between #' durations and periods. When used with a period object, as.duration provides #' an inexact estimate of the length of the period; each time unit is assigned #' its most common number of seconds. A period of one month is converted to #' 2628000 seconds (approximately 30.42 days). This ensures that 12 months will #' sum to 365 days, or one normal year. For an exact transformation, first #' transform the period to an interval with [as.interval()]. #' #' @param x Object to be coerced to a duration #' @param ... Parameters passed to other methods. Currently unused. #' @return A duration object #' @seealso [Duration-class], [duration()] #' @keywords classes manip methods chron #' @examples #' span <- interval(ymd("2009-01-01"), ymd("2009-08-01")) #interval #' as.duration(span) #' as.duration(10) # numeric #' dur <- duration(hours = 10, minutes = 6) #' as.numeric(dur, "hours") #' as.numeric(dur, "minutes") #' #' @aliases as.duration,numeric-method as.duration,logical-method #' as.duration,difftime-method as.duration,Interval-method #' as.duration,Duration-method as.duration,Period-method #' as.duration,character-method #' @export setGeneric("as.duration", function(x, ...) standardGeneric("as.duration"), useAsDefault = function(x, ...) { stop(sprintf("as.duration is not defined for class '%s'", class(x))) }) setMethod("as.duration", signature(x = "character"), function(x) { as.duration(as.period(x)) }) setMethod("as.duration", signature(x = "numeric"), function(x) { new("Duration", x) }) setMethod("as.duration", signature(x = "logical"), function(x) { new("Duration", as.numeric(x)) }) setMethod("as.duration", signature(x = "difftime"), function(x) { new("Duration", as.numeric(x, "secs")) }) setMethod("as.duration", signature(x = "Interval"), function(x) { new("Duration", x@.Data) }) setMethod("as.duration", signature(x = "Duration"), function(x) { x }) setMethod("as.duration", signature(x = "Period"), function(x) { new("Duration", period_to_seconds(x)) }) #' Change an object to an `interval` #' #' as.interval changes difftime, Duration, Period and numeric class objects to #' intervals that begin at the specified date-time. Numeric objects are first #' coerced to timespans equal to the numeric value in seconds. #' #' as.interval can be used to create accurate transformations between Period #' objects, which measure time spans in variable length units, and Duration objects, #' which measure timespans as an exact number of seconds. A start date- #' time must be supplied to make the conversion. Lubridate uses #' this start date to look up how many seconds each variable #' length unit (e.g. month, year) lasted for during the time span #' described. See #' [as.duration()], [as.period()]. #' #' @param x a duration, difftime, period, or numeric object that describes the length of the interval #' @param start a POSIXt or Date object that describes when the interval begins #' @param ... additional arguments to pass to as.interval #' @return an interval object #' @seealso [interval()] #' @keywords classes manip methods chron #' @examples #' diff <- make_difftime(days = 31) #difftime #' as.interval(diff, ymd("2009-01-01")) #' as.interval(diff, ymd("2009-02-01")) #' #' dur <- duration(days = 31) #duration #' as.interval(dur, ymd("2009-01-01")) #' as.interval(dur, ymd("2009-02-01")) #' #' per <- period(months = 1) #period #' as.interval(per, ymd("2009-01-01")) #' as.interval(per, ymd("2009-02-01")) #' #' as.interval(3600, ymd("2009-01-01")) #numeric #' @aliases as.interval,numeric-method as.interval,difftime-method as.interval,Interval-method as.interval,Duration-method as.interval,Period-method as.interval,POSIXt-method as.interval,logical-method #' @export as.interval <- function(x, start, ...) standardGeneric("as.interval") #' @export setGeneric("as.interval") setMethod("as.interval", signature(x = "numeric"), function(x, start, ...) { .number_to_interval(x, start, ...) }) setMethod("as.interval", signature(x = "difftime"), function(x, start, ...) { .number_to_interval(x, start, ...) }) setMethod("as.interval", signature(x = "Interval"), function(x, start, ...) { x }) setMethod("as.interval", signature(x = "POSIXt"), function(x, start, ...) { .number_to_interval(x, start, ...) }) #' @export setMethod("as.interval", signature("logical"), function(x, start, ...) { .number_to_interval(as.numeric(x), start, ...) }) .number_to_interval <- function(x, start, ...) { if (missing(start) & all(is.na(x))) start <- .POSIXct(NA_real_, tz = "UTC") else stopifnot(is.instant(start)) if (is.instant(x)) return(interval(x, start)) else interval(start, start + x) } #' Change an object to a period #' #' as.period changes Interval, Duration, difftime and numeric class objects #' to Period class objects with the specified units. #' #' Users must specify which time units to measure the period in. The exact length of #' each time unit in a period will depend on when it occurs. See #' [Period-class] and [period()]. #' The choice of units is not trivial; units that are #' normally equal may differ in length depending on when the time period #' occurs. For example, when a leap second occurs one minute is longer than 60 #' seconds. #' #' Because periods do not have a fixed length, they can not be accurately #' converted to and from Duration objects. Duration objects measure time spans #' in exact numbers of seconds, see [Duration-class]. Hence, a one to one #' mapping does not exist between durations and periods. When used with a #' Duration object, as.period provides an inexact estimate; the duration is #' broken into time units based on the most common lengths of time units, in #' seconds. Because the length of months are particularly variable, a period #' with a months unit can not be coerced from a duration object. For an exact #' transformation, first transform the duration to an interval with #' [as.interval()]. #' #' Coercing an interval to a period may cause surprising behavior if you request #' periods with small units. A leap year is 366 days long, but one year long. Such #' an interval will convert to 366 days when unit is set to days and 1 year when #' unit is set to years. Adding 366 days to a date will often give a different #' result than adding one year. Daylight savings is the one exception where this #' does not apply. Interval lengths are calculated on the UTC timeline, which does #' not use daylight savings. Hence, periods converted with seconds or minutes will not #' reflect the actual variation in seconds and minutes that occurs due to daylight #' savings. These periods will show the "naive" change in seconds and minutes that is #' suggested by the differences in clock time. See the examples below. #' #' @param x an interval, difftime, or numeric object #' @param unit A character string that specifies which time units to build period in. #' unit is only implemented for the as.period.numeric method and the as.period.interval method. #' For as.period.interval, as.period will convert intervals to units no larger than the specified #' unit. #' @param ... additional arguments to pass to as.period #' @return a period object #' @seealso [Period-class], [period()] #' @keywords classes manip methods chron #' @examples #' span <- interval(ymd_hms("2009-01-01 00:00:00"), ymd_hms("2010-02-02 01:01:01")) #interval #' as.period(span) #' as.period(span, unit = "day") #' "397d 1H 1M 1S" #' leap <- interval(ymd("2016-01-01"), ymd("2017-01-01")) #' as.period(leap, unit = "days") #' as.period(leap, unit = "years") #' dst <- interval(ymd("2016-11-06", tz = "America/Chicago"), #' ymd("2016-11-07", tz = "America/Chicago")) #' # as.period(dst, unit = "seconds") #' as.period(dst, unit = "hours") #' per <- period(hours = 10, minutes = 6) #' as.numeric(per, "hours") #' as.numeric(per, "minutes") #' #' @aliases as.period,numeric-method as.period,difftime-method #' as.period,Interval-method as.period,Duration-method as.period,Period-method #' as.period,logical-method as.period,character-method #' @export setGeneric("as.period", function(x, unit, ...) standardGeneric("as.period"), useAsDefault = function(x, unit, ...) { stop(sprintf("as.period is not defined for class '%s'", class(x))) }) setMethod("as.period", signature(x = "character"), function(x, ...) { parse_period(x) }) setMethod("as.period", signature(x = "numeric"), function(x, unit = "second", ...) { x <- as.numeric(x) if (missing(unit)) unit <- "second" unit <- standardise_date_names(unit) f <- get(paste(unit, "s", sep = ""), envir = asNamespace("lubridate"), mode = "function", inherits = FALSE) f(x) }) setMethod("as.period", signature(x = "difftime"), function(x, unit = NULL, ...) { seconds_to_period(as.double(x, "secs")) }) setMethod("as.period", signature(x = "Interval"), function(x, unit = NULL, ...) { ## fixme: document this in the manual ## SEMANTICS: for postitive intervals all units of the period will be ## positive, and the oposite for negatve intervals. ## Periods are not symetric in the sense that as.period(int) might not be the ## same as -as.period(int_flip(int)). See ## https://github.com/hadley/lubridate/issues/285 for motivation. unit <- if (missing(unit)) "year" else standardise_period_names(unit) switch(unit, year = .int_to_period(x), month = { pers <- .int_to_period(x) month(pers) <- month(pers) + year(pers)*12L year(pers) <- 0L pers }, ## fixme: add note to the docs that unit <= days results in much faster conversion ## fixme: add week day = , hour = , minute = , second = { secs <- x@.Data negs <- secs < 0 & !is.na(secs) units <- .units_within_seconds(abs(secs), unit) pers <- do.call("new", c("Period", units)) pers[negs] <- -pers[negs] pers }, stop("Unsuported unit ", unit)) }) .int_to_period <- function(x) { ## this function is called only for conversion with units > day start <- as.POSIXlt(x@start) end <- unclass(as.POSIXlt(start + x@.Data)) start <- unclass(start) negs <- x@.Data < 0 & !is.na(x@.Data) per <- list() for (nm in c("sec", "min", "hour", "mday", "mon", "year")) { per[[nm]] <- ifelse(negs, start[[nm]] - end[[nm]], end[[nm]] - start[[nm]]) } names(per) <- c("second", "minute", "hour", "day", "month", "year") ## Remove negative ... ## secons nsecs <- per$second < 0L & !is.na(per$second) per$second[nsecs] <- 60L + per$second[nsecs] per$minute[nsecs] <- per$minute[nsecs] - 1L per$second[negs] <- -per$second[negs] ## minutes nmins <- per$minute < 0L & !is.na(per$minute) per$minute[nmins] <- 60L + per$minute[nmins] per$hour[nmins] <- per$hour[nmins] - 1L per$minute[negs] <- -per$minute[negs] ## hours nhous <- per$hour < 0L & !is.na(per$hour) per$hour[nhous] <- 24L + per$hour[nhous] per$hour[negs] <- -per$hour[negs] ## days ### postivie periods ndays <- !negs & per$day < 0 & !is.na(per$day) if (any(ndays)) { ## compute nr days in previous month add_months <- rep.int(-1L, sum(ndays)) pmonth <- end$mon[ndays] pmonth[pmonth == 0L] <- 1L # dec == jan == 31 days prev_month_days <- .days_in_month(pmonth, end$year[ndays]) ## difference in days: ## /need pmax to capture as.period(interval(ymd("1985-01-31"), ymd("1986-03-28")))/ per$day[ndays] <- pmax(prev_month_days - start$mday[ndays], 0) + end$mday[ndays] per$month[ndays] <- per$month[ndays] + add_months } ## negative periods ndays <- negs & per$day < 0 & !is.na(per$day) if (any(ndays)) { add_months <- rep.int(1L, sum(ndays)) this_month_days <- .days_in_month(end$mon[ndays] + 1L, end$year[ndays]) ## Compute nr of days: ## /need pmax to capture as.period(interval(ymd("1985-01-31"), ymd("1986-03-28")))/ per$day[ndays] <- pmax(this_month_days - end$mday[ndays], 0) + start$mday[ndays] per$month[ndays] <- per$month[ndays] - add_months } ## substract only after the day computation to capture intervals like: ## as.period(interval(ymd_hms("1985-12-31 5:0:0"), ymd_hms("1986-02-01 3:0:0"))) per$day[nhous] <- per$day[nhous] - 1L per$day[negs] <- -per$day[negs] ## months nmons <- per$month < 0L & !is.na(per$month) per$month[nmons] <- 12L + per$month[nmons] per$year[nmons] <- per$year[nmons] - 1L per$month[negs] <- -per$month[negs] per$year[negs] <- -per$year[negs] new("Period", per$second, year = per$year, month = per$month, day = per$day, hour = per$hour, minute = per$minute) } setMethod("as.period", signature(x = "Duration"), function(x, unit = NULL, ...) { span <- x@.Data remainder <- abs(span) newper <- period(second = rep(0, length(x))) slot(newper, "year") <- remainder %/% (3600 * 24 * 365) remainder <- remainder %% (3600 * 24 * 365) slot(newper, "day") <- remainder %/% (3600 * 24) remainder <- remainder %% (3600 * 24) slot(newper, "hour") <- remainder %/% (3600) remainder <- remainder %% (3600) slot(newper, "minute") <- remainder %/% (60) newper$second <- remainder %% (60) newper * sign(span) }) setMethod("as.period", signature("Period"), function(x, unit = NULL, ...) { if (missing(unit) || is.null(unit)) { x } else { unit <- standardise_period_names(unit) switch(unit, year = x, month = { month(x) <- month(x) + year(x)*12L year(x) <- 0L x }, day = , hour = , minute = , second = { N <- .units_within_seconds(period_to_seconds(x), unit) do.call("new", c("Period", N)) }, stop("Unsuported unit ", unit)) } }) setMethod("as.period", signature("logical"), function(x, unit = NULL, ...) { as.period(as.numeric(x), unit, ...) }) #' @export setGeneric("as.difftime") #' @export setMethod("as.difftime", signature(tim = "Interval"), function(tim, format = "%X", units = "secs") { as.difftime(as.numeric(tim, units), format, units) }) #' @export setMethod("as.difftime", signature(tim = "Duration"), function(tim, format = "%X", units = "secs") { as.difftime(tim@.Data, format, units) }) #' @export setMethod("as.difftime", signature(tim = "Period"), function(tim, format = "%X", units = "secs") { as.difftime(period_to_seconds(tim), format, units) }) setGeneric("as.numeric") seconds_to_unit <- function(secs, unit = "second") { switch(unit, second = secs, minute = secs / 60, hour = secs / 3600, day = secs / 86400, month = secs / (86400 * 365.25 / 12), week = secs / (86400 * 7), year = secs / (86400 * 365.25), stop("invalid unit ", unit)) } #' @export setMethod("as.numeric", signature("Duration"), function(x, units = "secs", ...) { unit <- standardise_period_names(units) as.numeric(seconds_to_unit(x@.Data, unit), ...) }) #' @export setMethod("as.numeric", signature(x = "Interval"), function(x, units = "secs", ...) { as.numeric(as.duration(x), units, ...) }) #' @export setMethod("as.numeric", signature(x = "Period"), function(x, units = "second", ...) { unit <- standardise_period_names(units) as.numeric(seconds_to_unit(period_to_seconds(x), unit = unit), ...) }) as.POSIXt <- function(x) as.POSIXlt(x) #' @export setMethod("as.character", signature(x = "Period"), function(x, ...) { format(x) }) #' @export setMethod("as.character", signature(x = "Duration"), function(x, ...) { format(x) }) #' @export setMethod("as.character", signature(x = "Interval"), function(x, ...) { format(x) }) #' Convert an object to a date or date-time #' #' #' @section Compare to base R: #' #' These are drop in replacements for [as.Date()] and [as.POSIXct()], with a few #' tweaks to make them work more intuitively. #' #' \itemize{ #' \item `as_date()` ignores the timezone attribute, resulting in #' a more intuitive conversion (see examples) #' \item Both functions provide a default origin argument for numeric #' vectors. #' \item `as_datetime()` defaults to using UTC. #' } #' #' @param x a vector of [POSIXt], numeric or character objects #' @param origin a Date object, or something which can be coerced by #' `as.Date(origin, ...)` to such an object (default: the Unix epoch of #' "1970-01-01"). Note that in this instance, `x` is assumed to reflect the #' number of days since `origin` at `"UTC"`. #' @param tz a time zone name (default: time zone of the POSIXt object `x`). See #' [OlsonNames()]. #' @param format format argument for character methods. When supplied parsing is #' performed by [strptime()]. For this reason consider using specialized #' parsing functions in lubridate. #' @param ... further arguments to be passed to specific methods (see above). #' @return a vector of [Date] objects corresponding to `x`. #' @examples #' dt_utc <- ymd_hms("2010-08-03 00:50:50") #' dt_europe <- ymd_hms("2010-08-03 00:50:50", tz="Europe/London") #' c(as_date(dt_utc), as.Date(dt_utc)) #' c(as_date(dt_europe), as.Date(dt_europe)) #' ## need not supply origin #' as_date(10) #' @export setGeneric(name = "as_date", def = function(x, ...) standardGeneric("as_date")) #' @rdname as_date #' @export setMethod("as_date", "ANY", function(x, ...) { ## From: Kurt Hornik ## Date: Tue, 3 Apr 2018 18:53:19 ## ## `zoo` has its own as.Date for which it registers its yearmon ## method (and base::as.Date as the default S3 method). In fact, ## zoo also exports as.Date.yearmon etc, but the above ## ## lubridate::as_date(zoo::as.yearmon("2011-01-07")) ## ## does not attach the zoo exports, hence does not find ## as.Date.yearmon on the search path. if (inherits(x, c("yearmon", "yearqtr"))) zoo::as.Date(x, ...) else base::as.Date(x, ...) }) #' @rdname as_date #' @export setMethod(f = "as_date", signature = "POSIXt", function(x, tz = NULL) { tz <- if (is.null(tz)) tz(x) else tz as.Date(x, tz = tz) }) #' @rdname as_date setMethod(f = "as_date", signature = "numeric", function(x, origin = lubridate::origin) { as.Date(x, origin = origin) }) #' @rdname as_date #' @export setMethod("as_date", "character", function(x, tz = NULL, format = NULL) { if (is.null(format)) as_date(as_datetime(x, tz = "UTC")) else as_date(strptime(x, format, tz)) }) #' @rdname as_date #' @export setGeneric("as_datetime", function(x, ...) { standardGeneric("as_datetime") }) #' @rdname as_date #' @export setMethod("as_datetime", "POSIXt", function(x, tz = "UTC") { with_tz(x, tz) }) #' @rdname as_date #' @export setMethod("as_datetime", "numeric", function(x, origin = lubridate::origin, tz = "UTC") { as.POSIXct(x, origin = origin, tz = tz) }) #' @rdname as_date #' @export setMethod("as_datetime", "character", function(x, tz = "UTC", format = NULL) { if (is.null(format)) .parse_iso_dt(x, tz) else strptime(x, format = format, tz = tz) }) #' @rdname as_date #' @export setMethod("as_datetime", "ANY", function(x, tz = "UTC") { with_tz(as.POSIXct(x), tzone = tz) }) lubridate/R/leap-years.r0000644000176200001440000000146013102102352014641 0ustar liggesusers#' Is a year a leap year? #' #' If x is a recognized date-time object, leap_year will return whether x #' occurs during a leap year. If x is a number, leap_year returns whether it #' would be a leap year under the Gregorian calendar. #' #' @export leap_year #' @param date a date-time object or a year #' @return TRUE if x is a leap year, FALSE otherwise #' @keywords logic chron #' @examples #' x <- as.Date("2009-08-02") #' leap_year(x) # FALSE #' leap_year(2009) # FALSE #' leap_year(2008) # TRUE #' leap_year(1900) # FALSE #' leap_year(2000) # TRUE leap_year <- function(date) { recognized <- recognize(date) if (recognized) year <- year(date) else if (all(is.numeric(date))) year <- date else stop("unrecognized date format") (year %% 4 == 0) & ((year %% 100 != 0) | (year %% 400 == 0)) } lubridate/R/time-zones.r0000644000176200001440000001364013263116135014710 0ustar liggesusers#' Get date-time in a different time zone #' #' with_tz returns a date-time as it would appear in a different time zone. #' The actual moment of time measured does not change, just the time zone it is #' measured in. with_tz defaults to the Universal Coordinated time zone (UTC) #' when an unrecognized time zone is inputted. See [Sys.timezone()] #' for more information on how R recognizes time zones. #' #' @param time a POSIXct, POSIXlt, Date, chron date-time object or a data.frame #' object. When a data.frame all POSIXt elements of a data.frame are processed #' with `with_tz()` and new data.frame is returned. #' @param tzone a character string containing the time zone to convert to. R #' must recognize the name contained in the string as a time zone on your #' system. #' @return a POSIXct object in the updated time zone #' @keywords chron manip #' @seealso [force_tz()] #' @examples #' x <- ymd_hms("2009-08-07 00:00:01", tz = "America/New_York") #' with_tz(x, "GMT") #' @export with_tz <- function (time, tzone = "") { if (!C_valid_tz(tzone)) warning(sprintf("Unrecognized time zone '%s'", tzone)) if (is.data.frame(time)) { for (nm in names(time)) { if (is.POSIXt(time[[nm]])) { time[[nm]] <- .with_tz(time[[nm]], tzone = tzone) } } time } else { .with_tz(time, tzone) } } .with_tz <- function (time, tzone = "") { new <- if (is.POSIXlt(time)) as.POSIXct(time) else time attr(new, "tzone") <- tzone reclass_date(new, time) } #' Replace time zone to create new date-time #' #' `force_tz` returns the date-time that has the same clock time as input time, #' but in the new time zone. `force_tzs` is the parallel version of `force_tz`, #' meaning that every element from `time` argument is matched with the #' corresponding time zone in `tzones` argument. #' #' Although the new date-time has the same clock time (e.g. the same values in #' the year, month, days, etc. elements) it is a different moment of time than #' the input date-time. #' #' As R date-time vectors cannot hold elements with non-uniform time zones, #' `force_tzs` returns a vector with time zone `tzone_out`, UTC by default. #' #' @param time a POSIXct, POSIXlt, Date, chron date-time object, or a data.frame #' object. When a data.frame all POSIXt elements of a data.frame are processed #' with `force_tz()` and new data.frame is returned. #' @param tzone a character string containing the time zone to convert to. R #' must recognize the name contained in the string as a time zone on your #' system. #' @param roll logical. If TRUE, and `time` falls into the DST-break, assume #' the next valid civil time, otherwise return NA. See examples. #' @return a POSIXct object in the updated time zone #' @keywords chron manip #' @seealso [with_tz()], [local_time()] #' @examples #' x <- ymd_hms("2009-08-07 00:00:01", tz = "America/New_York") #' force_tz(x, "UTC") #' force_tz(x, "Europe/Amsterdam") #' #' ## DST skip: #' #' y <- ymd_hms("2010-03-14 02:05:05 UTC") #' force_tz(y, "America/New_York", roll=FALSE) #' force_tz(y, "America/New_York", roll=TRUE) #' @export force_tz <- function(time, tzone = "", roll = FALSE) { tzone <- as.character(tzone) if (is.data.frame(time)) { for (nm in names(time)) { if (is.POSIXt(time[[nm]])) { time[[nm]] <- force_tz(time[[nm]], tzone = tzone) } } time } else { if (is.POSIXct(time)) C_force_tz(time, tz = tzone, roll) else if (is.Date(time)) as_date(C_force_tz(date_to_posix(time), tz = tzone, roll)) else { out <- C_force_tz(as.POSIXct(time, tz = tz(time)), tz = tzone, roll) reclass_date(out, time) } } } #' @param tzones character vector of timezones to be "enforced" on `time` time #' stamps. If `time` and `tzones` lengths differ, the smaller one is recycled #' in accordance with usual R conventions. #' @param tzone_out timezone of the returned date-time vector (for `force_tzs`). #' @rdname force_tz #' @examples #' #' ## Heterogeneous time-zones: #' #' x <- ymd_hms(c("2009-08-07 00:00:01", "2009-08-07 01:02:03")) #' force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam")) #' force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam"), tzone_out = "America/New_York") #' #' x <- ymd_hms("2009-08-07 00:00:01") #' force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam")) #' @export force_tzs <- function(time, tzones, tzone_out = "UTC", roll = FALSE) { if (length(tzones) < length(time)) tzones <- rep_len(tzones, length(time)) else if (length(tzones) > length(time)) { attr <- attributes(time) time <- rep_len(time, length(tzones)) attributes(time) <- attr } out <- C_force_tzs(as.POSIXct(time), tzones, tzone_out, roll) reclass_date(out, time) } #' Get local time from a date-time vector. #' #' `local_time` retrieves day clock time in specified time zones. Computation is #' vectorized over both `dt` and `tz` arguments, the shortest is recycled in #' accordance with standard R rules. #' #' @param dt a date-time object. #' @param tz a character vector of timezones for which to compute the local time. #' @param units passed directly to [as.difftime()]. #' @examples #' #' x <- ymd_hms(c("2009-08-07 01:02:03", "2009-08-07 10:20:30")) #' local_time(x, units = "secs") #' local_time(x, units = "hours") #' local_time(x, "Europe/Amsterdam") #' local_time(x, "Europe/Amsterdam") == local_time(with_tz(x, "Europe/Amsterdam")) #' #' x <- ymd_hms("2009-08-07 01:02:03") #' local_time(x, c("America/New_York", "Europe/Amsterdam", "Asia/Shanghai"), unit = "hours") #' @export local_time <- function(dt, tz = NULL, units = "secs") { if (is.null(tz)) tz <- tz(dt) if (length(tz) < length(dt)) tz <- rep_len(tz, length(dt)) else if (length(tz) > length(dt)) { attr <- attributes(dt) dt <- rep_len(dt, length(tz)) attributes(dt) <- attr } secs <- C_local_time(as.POSIXct(dt), tz) out <- structure(secs, units = "secs", class = "difftime") units(out) <- units out } lubridate/R/RcppExports.R0000644000176200001440000000146313263152632015051 0ustar liggesusers# Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 C_local_tz <- function() { .Call(`_lubridate_C_local_tz`) } C_valid_tz <- function(tz_name) { .Call(`_lubridate_C_valid_tz`, tz_name) } C_update_dt <- function(dt, year, month, yday, mday, wday, hour, minute, second, tz = NULL, roll = FALSE, week_start = 7L) { .Call(`_lubridate_C_update_dt`, dt, year, month, yday, mday, wday, hour, minute, second, tz, roll, week_start) } C_force_tz <- function(dt, tz, roll = FALSE) { .Call(`_lubridate_C_force_tz`, dt, tz, roll) } C_force_tzs <- function(dt, tzs, tz_out, roll = FALSE) { .Call(`_lubridate_C_force_tzs`, dt, tzs, tz_out, roll) } C_local_time <- function(dt, tzs) { .Call(`_lubridate_C_local_time`, dt, tzs) } lubridate/R/guess.r0000644000176200001440000004073313234630403013744 0ustar liggesusers##' Guess possible date-times formats from a character vector ##' ##' @param x input vector of date-times ##' @param orders format orders to look for. See examples. ##' @param locale locale to use, default to the current locale ##' @param preproc_wday whether to preprocess week days names. Internal ##' optimization used by ymd_hms family of functions. If TRUE, weekdays are ##' substituted with %a or %A accordingly, so that there is no need to supply ##' this format explicitly. ##' @param print_matches for development purpose mainly. If TRUE prints a matrix ##' of matched templates. ##' @return a vector of matched formats ##' @export ##' @examples ##' ##' x <- c('February 20th 1973', ##' "february 14, 2004", ##' "Sunday, May 1, 2000", ##' "Sunday, May 1, 2000", ##' "february 14, 04", ##' 'Feb 20th 73', ##' "January 5 1999 at 7pm", ##' "jan 3 2010", ##' "Jan 1, 1999", ##' "jan 3 10", ##' "01 3 2010", ##' "1 3 10", ##' '1 13 89', ##' "5/27/1979", ##' "12/31/99", ##' "DOB:12/11/00", ##' "-----------", ##' 'Thu, 1 July 2004 22:30:00', ##' 'Thu, 1st of July 2004 at 22:30:00', ##' 'Thu, 1July 2004 at 22:30:00', ##' 'Thu, 1July2004 22:30:00', ##' 'Thu, 1July04 22:30:00', ##' "21 Aug 2011, 11:15:34 pm", ##' "-----------", ##' "1979-05-27 05:00:59", ##' "1979-05-27", ##' "-----------", ##' "3 jan 2000", ##' "17 april 85", ##' "27/5/1979", ##' '20 01 89', ##' '00/13/10', ##' "-------", ##' "14 12 00", ##' "03:23:22 pm") ##' ##' guess_formats(x, "BdY") ##' guess_formats(x, "Bdy") ##' ## m also matches b and B; y also matches Y ##' guess_formats(x, "mdy", print_matches = TRUE) ##' ##' ## T also matches IMSp order ##' guess_formats(x, "T", print_matches = TRUE) ##' ##' ## b and B are equivalent and match, both, abreviated and full names ##' guess_formats(x, c("mdY", "BdY", "Bdy", "bdY", "bdy"), print_matches = TRUE) ##' guess_formats(x, c("dmy", "dbY", "dBy", "dBY"), print_matches = TRUE) ##' ##' ##' guess_formats(x, c("dBY HMS", "dbY HMS", "dmyHMS", "BdY H"), print_matches = TRUE) ##' ##' guess_formats(x, c("ymd HMS"), print_matches = TRUE) ##' guess_formats <- function(x, orders, locale = Sys.getlocale("LC_TIME"), preproc_wday = TRUE, print_matches = FALSE) { ## remove all separators orders <- gsub("[^[:alpha:]]+", "", orders) if (any(grepl("hms|hm|ms", orders))) { .deprecated("hms, hm and ms usage", ", please use HMS, HM or MS instead", "1.5.6") orders <- gsub("hms", "HMS", orders, ignore.case = TRUE) orders <- gsub("hm", "HM", orders, ignore.case = TRUE) orders <- gsub("ms", "MS", orders, ignore.case = TRUE) } ## redirect some formats to C parser (using perl's lookbehind) if (length(wp <- grepl("(? 0) { ospt[which_O + 1] <- paste("O", ospt[which_O + 1], sep = "") ospt[-which_O] } else ospt }) reg <- .get_locale_regs(locale) flex_regs <- c(reg$alpha_flex, reg$num_flex, .c_parser_reg_flex) exact_regs <- c(reg$alpha_exact, reg$num_exact, .c_parser_reg_exact) REGS <- unlist(lapply(osplits, function(fnames) { ## fnames are names of smalest valid formats, like a, A, b, z, OS, OZ ... which <- !fnames %in% c(names(reg$alpha_flex), names(reg$num_flex), names(.c_parser_reg_exact)) if (any(which)) stop("Unknown formats supplied: ", paste(fnames[ which ], sep = ", ")) ## restriction: no numbers before or after ## fixme: using \\D*? because \\D+ doesn't work in flex match, why? paste("^\\D*?\\b((", paste(unlist(flex_regs[fnames]), collapse = "\\D*?"), ")|(", paste(unlist(exact_regs[fnames]), collapse = "\\D*?"), "))\\D*$", sep = "") })) ## print debugging info if (print_matches) { subs <- lapply(REGS, .substitute_formats, x, fmts_only = FALSE) names(subs) <- orders print(do.call(cbind, c(list(x), subs))) } .build_formats <- function(regs, orders, x) { out <- mapply( function(reg, name) { out <- .substitute_formats(reg, x) if (!is.null(out)) names(out) <- rep.int(name, length(out)) out }, REGS, orders, SIMPLIFY = F, USE.NAMES = F) names(out) <- NULL unlist(out) } if (preproc_wday && !any(grepl("[aA]", orders))) { ## replace short/long weak days in current locale x2 <- gsub(reg$alpha_exact[["A"]], "%A", x, ignore.case = T, perl = T) x2 <- gsub(reg$alpha_exact[["a"]], "%a", x2, ignore.case = T, perl = T) formats <- .build_formats(REGS, orders, x2) ## In some locales abreviated day (italian "gio") is part of month name ## ("maggio"). So check if %a or %A is present and append wday-less formats. if (any(grepl("%[aA]", formats))) c(formats, .build_formats(REGS, orders, x)) else formats } else { .build_formats(REGS, orders, x) } } .substitute_formats <- function(reg, x, fmts_only = TRUE) { ## Take date X and substitute year with %Y/%y, month with %B/%b etc. ## Return the formatted string if REG matched, or null otherwise. ## REG should be with captures as build by .build_locale_regs ## Captures should start with the strptyme formats. For example Y_e, B_m_e ## Traling _e, _m_e are removed. ## fmts_only == FALSE is for debugging purpose only m <- regexpr(reg, x, ignore.case = TRUE, perl = TRUE) ## print(regs[[1]]) matched <- m > 0 if (any(matched)) { nms <- attr(m, "capture.names") nms <- nms[nzchar(nms)] ## e <- grepl("_e", nms, fixed = TRUE) ## nms_e <- nms[e] ## nms <- nms[!e] start <- attr(m, "capture.start")[matched, , drop = FALSE] end <- start + attr(m, "capture.length")[matched, , drop = FALSE] - 1L lout <- x[matched] for (n in rev(nms)) { ## start from the end w <- end[, n] > 0 ## -1 if unmatched subpatern str_sub(lout[w], start[w, n], end[w, n]) <- paste("%", gsub("_.*$", "", n), sep = "") } if (fmts_only) lout else { ## developer out <- character(length(x)) ## dev only out[matched] <- lout out } } else if (fmts_only) NULL else character(length(x)) } .enclose <- function(fmts) paste("@", fmts, "@", sep = "") .enclosed.na <- function(x) x == "@NA@" .get_train_set <- function(x) { ## the best irregular guesser I could come up with x <- x[!.enclosed.na(x)] len <- length(x) if (len < 100) x else if (len < 3571) x[.primes[.primes <= length(x) ] ] else x[ .primes * (length(x) %/% 3571) ] # 501 primes } .train_formats <- function(x, formats, locale) { ## return a numeric vector of size length(formats), with each element giving ## the number of matched elements in X ## can return NULL if formats is NULL trials <- lapply(formats, function(fmt) .strptime(x, fmt, locale = locale)) successes <- unlist(lapply(trials, function(x) sum(!is.na(x))), use.names = FALSE) names(successes) <- formats sort(successes, decreasing = TRUE) } .best_formats <- function(x, orders, locale, .select_formats, drop = FALSE) { ## return a vector of formats that matched X at least once. ## Can be zero length vector, if none matched fmts <- unique(guess_formats(x, orders, locale = locale, preproc_wday = TRUE)) # orders as names if (length(fmts)) { trained <- .train_formats(x, fmts, locale = locale) if (drop) trained <- trained[ trained > 0 ] .select_formats(trained, drop) } } .select_formats <- function(trained, drop = FALSE) { nms <- names(trained) score <- nchar(gsub("[^%]", "", nms)) + ## longer formats have priority grepl("%Y", nms, fixed = T)*1.5 + grepl("%y(?!%)", nms, perl = T)*1.6 + ## y has priority over Y, but only when not followed by % grepl("%[Bb]", nms)*.31 + ## B/b format has priority over %Om ## C parser formats have higher priority grepl("%Om", nms)*.3 + grepl("%Op", nms)*.3 + grepl("%Ob", nms)*.32 ## Ob has higher priority than B/b ## ties are broken by `trained` n0 <- trained != 0 if (drop) { score <- score[n0] trained <- trained[n0] } else { score[!n0] <- -100 } ## print(rbind(trained, score)) names(trained)[order(score, trained, decreasing = T)] } ## These are formats that are effectively matched by c parser. But we must get ## through the format guesser first for ymd_hms family. .c_parser_reg_flex <- list(Op = "(?(AM|PM))(?![[:alpha:]])", Om = "((?1[0-2]|0?[1-9](?!\\d))|(((?Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)|(?January|February|March|April|May|June|July|August|September|October|November|December))(?![[:alpha:]])))", Ob = "(((?Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)|(?January|February|March|April|May|June|July|August|September|October|November|December))(?![[:alpha:]]))") .c_parser_reg_exact <- list(Op = "(?AM|PM)(?![[:alpha:]])", Om = "((?1[0-2]|0[1-9])|(((?Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)|(?January|February|March|April|May|June|July|August|September|October|November|December))(?![[:alpha:]])))", Ob = "(((?Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)|(?January|February|March|April|May|June|July|August|September|October|November|December))(?![[:alpha:]]))") .locale_reg_cache <- new.env(hash = FALSE) .get_locale_regs <- function(locale = Sys.getlocale("LC_TIME")) { ## build locale specific regexps for all posible orders if (exists(locale, envir = .locale_reg_cache, inherits = FALSE)) return(get(locale, envir = .locale_reg_cache)) orig_opt <- options(warn = 5) on.exit({Sys.setlocale("LC_TIME", orig_locale) options(orig_opt)}) orig_locale <- Sys.getlocale("LC_TIME") Sys.setlocale("LC_TIME", locale) options(orig_opt) format <- "%a@%A@%b@%B@%p@" L <- enc2utf8(unique(format(.date_template, format = format))) mat <- do.call(rbind, strsplit(L, "@", fixed = TRUE)) mat[] <- gsub("([].|(){^$*+?[])", "\\\\\\1", mat) ## escaping all meta chars names <- colnames(mat) <- strsplit(format, "[%@]+")[[1]][-1L] ## Captures should be unique. Thus we build captures with the following ## rule. Capture starts with the name of strptime format (B, b, y etc) It ends ## with _e if the expression is an exact match (as oposed to flex), see below. ## It can contain _x where x is a main format in which this format ## occurs. For example is an exact capture in the strptime format B ## but that also matches b in lubridate. Try lubridate:::.get_loc_regs() ## todo: elaborate ## ALPHABETIC FORMATS alpha <- list() alpha["b"] <- sprintf("((?%s)|(?%s))(?![[:alpha:]])", paste(unique(mat[, "b"]), collapse = "|"), paste(unique(mat[, "B"]), collapse = "|")) alpha["B"] <- sprintf("(?%s)(?![[:alpha:]])", paste(unique(mat[, "B"]), collapse = "|")) alpha["a"] <- sprintf("((?%s)|(?%s))(?![[:alpha:]])", paste(unique(mat[, "a"]), collapse = "|"), paste(unique(mat[, "A"]), collapse = "|")) alpha["A"] <- sprintf("(?%s)(?![[:alpha:]])", paste(unique(mat[, "A"]), collapse = "|")) ## just match Z in ISO8601, (UTC zulu format) alpha["Ou"] <- "(?Z)(?![[:alpha:]])" p <- unique(mat[, "p"]) p <- p[nzchar(p)] alpha["p"] <- if (length(p) == 0L) "" else sprintf("(?

%s)(?![[:alpha:]])", paste(p, collapse = "|")) alpha <- unlist(alpha) ## NUMERIC FORMATS num <- num_flex <- num_exact <- c( d = "(?[012]?[1-9]|3[01]|[12]0)", q = "(?[0]?[1-4])", H = "(?2[0-4]|[01]?\\d)", h = "(?2[0-4]|[01]?\\d)", I = "(?1[0-2]|0?[1-9])", j = "(?[0-3]?\\d?\\d)", M = "(?[0-5]?\\d)", S = "((?[0-5]?\\d\\.\\d+)|(?[0-6]?\\d))", s = "((?[0-5]?\\d\\.\\d+)|(?[0-6]?\\d))", U = "(?[0-5]?\\d)", w = "(?[0-6])", # merge with a, A?? u = "(?[1-7])", W = "(?[0-5]?\\d)", ## x = "(?\\d{2}/[01]?\\d/[0-3]?\\d)", ## X = "(?[012]?\\d:[0-5]?\\d:[0-6]?\\d)", Y = "(?\\d{4})", y = "((?\\d{4})|(?\\d{2}))", Oz = "(?[-+]\\d{4})", ## sptrtime implements only this format (4 digits) ## F = "(?\\d{4)-\\d{2}-\\d{2})", OO = "(?[-+]\\d{2}:\\d{2})", Oo = "(?[-+]\\d{2})") ## special lubridate formats nms <- c("T", "R", "r") ## in some locales %p = "" if (length(p) == 0L) { num <- c(num, T = sprintf("(%s\\D+%s\\D+%s)", num[["H"]], num[["M"]], num[["S"]]), R = sprintf("(%s\\D+%s)", num[["H"]], num[["M"]]), r = sprintf("(%s\\D+)", num[["H"]])) } else { num <- c(num, T = sprintf("((%s\\D+%s\\D+%s\\D*%s)|(%s\\D+%s\\D+%s))", num[["I"]], num[["M"]], num[["S"]], alpha[["p"]], num[["H"]], num[["M"]], num[["S"]]), R = sprintf("((%s\\D+%s\\D*%s)|(%s\\D+%s))", num[["I"]], num[["M"]], alpha[["p"]], num[["H"]], num[["M"]]), r = sprintf("((%s\\D*%s)|%s)", num[["I"]], alpha[["p"]], num[["H"]])) num[nms] <- sub("", "_e>", alpha, fixed = TRUE) num_exact <- num_flex <- num num_flex[] <- sprintf("%s(?!\\d)", num) num_exact[] <- gsub("(?", "_e>", num))) # append _e to avoid duplicates num_flex["m"] <- sprintf("((?1[0-2]|0?[1-9](?!\\d))|(%s))", gsub("_[bB]", "\\1_m", alpha[["b"]])) num_exact["m"] <- sprintf("((?1[0-2]|0[1-9])|(%s))", gsub("_[bB]", "\\1_m_e", alpha[["b"]])) ## canoot be in num above because gsub("+", "*") messes it up num_flex["OS"] <- "(?[0-5]\\d\\.\\d+)" num_exact["OS"] <- "(?[0-5]\\d\\.\\d+)" num_flex["z"] <- sprintf("(%s|%s|%s|%s)", alpha_flex[["Ou"]], num_flex[["Oz"]], num_flex[["OO"]], num_flex[["Oo"]]) num_exact["z"] <- sprintf("(%s|%s|%s|%s)", alpha_exact[["Ou"]], num_exact[["Oz"]], num_exact[["OO"]], num_exact[["Oo"]]) wday_order <- order(wday(.date_template, week_start = 7)) wday_names <- list(abr = unique(mat[, "a"][wday_order]), full = unique(mat[, "A"][wday_order])) month_order <- order(month(.date_template)) month_names <- list(abr = unique(mat[, "b"][month_order]), full = unique(mat[, "B"][month_order])) out <- list(alpha_flex = alpha_flex, num_flex = num_flex, alpha_exact = alpha_exact, num_exact = num_exact, wday_names = wday_names, month_names = month_names) assign(locale, out, envir = .locale_reg_cache) out } lubridate/R/update.r0000644000176200001440000002145213236356705014111 0ustar liggesusers#' Changes the components of a date object #' #' `update.Date()` and `update.POSIXt()` return a date with the specified #' elements updated. Elements not specified will be left unaltered. update.Date #' and update.POSIXt do not add the specified values to the existing date, they #' substitute them for the appropriate parts of the existing date. #' #' #' @name DateTimeUpdate #' @param object a date-time object #' @param ... named arguments: years, months, ydays, wdays, mdays, days, hours, #' minutes, seconds, tzs (time zone compnent) #' @param roll logical. If `TRUE`, and the resulting date-time lands on a #' non-existent civil time instant (DST, 29th February, etc.) roll the date #' till next valid point. When `FALSE`, the default, produce NA for non #' existing date-times. #' @param week_start week starting day (Default is 7, Sunday). Set #' `lubridate.week.start` option to control this. #' @param simple logical. Deprecated. Same as `roll`. #' @return a date object with the requested elements updated. The object will #' retain its original class unless an element is updated which the original #' class does not support. In this case, the date returned will be a POSIXlt #' date object. #' @keywords manip chron #' @examples #' date <- ymd("2009-02-10") #' update(date, year = 2010, month = 1, mday = 1) #' #' update(date, year =2010, month = 13, mday = 1) #' #' update(date, minute = 10, second = 3) #' @export update.POSIXt <- function(object, ..., roll = FALSE, week_start = getOption("lubridate.week.start", 7), simple = NULL) { if (!is.null(simple)) roll <- simple do.call(update_date_time, c(list(object, roll = roll, week_start = week_start), list(...))) } update_date_time <- function(object, years = integer(), months = integer(), days = integer(), mdays = integer(), ydays = integer(), wdays = integer(), hours = integer(), minutes = integer(), seconds = double(), tzs = NULL, roll = FALSE, week_start = 7) { if (!length(object)) return(object) if (length(days) > 0) mdays = days; updates <- list(year = years, month = months, yday = ydays, mday = mdays, wday = wdays, hour = hours, minute = minutes, second = seconds) maxlen <- max(unlist(lapply(updates, length))) if (maxlen > 1) { for (nm in names(updates)) { len <- length(updates[[nm]]) ## len == 1 is treated at C_level if (len != maxlen && len > 1) updates[[nm]] <- rep_len(updates[[nm]], maxlen) } } if (is.null(tzs)) tzs <- tz(object) ## todo: check if the following lines make any unnecessary copies updates[["dt"]] <- as.POSIXct(object) updates[["roll"]] <- roll updates[["tz"]] <- tzs updates[["week_start"]] <- week_start reclass_date(do.call(C_update_dt, updates), object) } ## prior to v1.7.0 update_posixt_old <- function(object, ..., simple = FALSE) { if (!length(object)) return(object) date <- as.POSIXlt(object) ## adjudicate units input units <- list(...) names(units) <- standardise_lt_names(names(units)) if (!is.null(new_tz <- units$tz)) { units$tz <- NULL } day.units <- c("day", "wday", "mday", "yday") wunit <- day.units %in% names(units) if (n <- sum(wunit)) { if (n > 1) stop("conflicting days input") uname <- day.units[wunit] if (uname != "mday") { ## we compute everything with mdays (operating with ydays doesn't work) if (uname != "day") { if (uname == "yday" & !is.null(units$year)) warning("Updating on both 'year' and 'yday' can lead to wrong results. See bug #319.", call. = F) diff <- units[[uname]] - date[[uname]] - 1 units[[uname]] <- diff + date$mday } names(units)[names(units) == uname] <- "mday" } } if (!is.null(units$mon)) units$mon <- units$mon - 1 if (!is.null(units$year)) units$year <- units$year - 1900 ## make new date-times date <- unclass(date) date[names(units)] <- units date[c("wday", "yday")] <- list(wday = NA, yday = NA) ## unbalanced POSIXlt often results in R crashes maxlen <- max(unlist(lapply(date, length))) if (maxlen > 1) { for (nm in names(date)) if (length(date[[nm]]) != maxlen) date[[nm]] <- rep_len(date[[nm]], maxlen) } class(date) <- c("POSIXlt", "POSIXt") if (!is.null(new_tz)) attr(date, "tzone") <- new_tz ## fit to timeline ## POSIXct format avoids negative and NA elements in POSIXlt format fit_to_timeline(date, class(object)[[1]], simple = simple) } #' @export update.Date <- function(object, ...) { ct <- as_datetime(object, tz = "UTC") new <- update(ct, ...) ## fixme: figure out a way to avoid this, or write specialized update for Date new_lt <- as.POSIXlt(new, tz = "UTC") if (sum(c(new_lt$hour, new_lt$min, new_lt$sec), na.rm = TRUE)) { new } else { make_date(new_lt$year + 1900, new_lt$mon + 1, new_lt$mday) } } #' Fit a POSIXlt date-time to the timeline #' #' The POSIXlt format allows you to create instants that do not exist in real #' life due to daylight savings time and other conventions. fit_to_timeline #' matches POSIXlt date-times to a real times. If an instant does not exist, fit #' to timeline will replace it with an NA. If an instant does exist, but has #' been paired with an incorrect timezone/daylight savings time combination, #' fit_to_timeline returns the instant with the correct combination. #' #' #' @param lt a POSIXlt date-time object. #' @param class a character string that describes what type of object to return, #' POSIXlt or POSIXct. Defaults to POSIXct. This is an optimization to avoid #' needless conversions. #' @param simple if TRUE, \pkg{lubridate} makes no attempt to detect #' meaningless time-dates or to correct time zones. No NAs are produced and #' the most meaningful valid dates are returned instead. See examples. #' @return a POSIXct or POSIXlt object that contains no illusory date-times #' #' @examples #' \dontrun{ #' #' tricky <- structure(list(sec = c(5, 0, 0, -1), #' min = c(0L, 5L, 5L, 0L), #' hour = c(2L, 0L, 2L, 2L), #' mday = c(4L, 4L, 14L, 4L), #' mon = c(10L, 10L, 2L, 10L), #' year = c(112L, 112L, 110L, 112L), #' wday = c(0L, 0L, 0L, 0L), #' yday = c(308L, 308L, 72L, 308L), #' isdst = c(1L, 0L, 0L, 1L)), #' .Names = c("sec", "min", "hour", "mday", "mon", #' "year", "wday", "yday", "isdst"), #' class = c("POSIXlt", "POSIXt"), #' tzone = c("America/Chicago", "CST", "CDT")) #' #' tricky #' ## [1] "2012-11-04 02:00:00 CDT" Doesn't exist because clocks "fall back" to 1:00 CST #' ## [2] "2012-11-04 00:05:00 CST" Times are still CDT, not CST at this instant #' ## [3] "2010-03-14 02:00:00 CDT" DST gap #' ## [4] "2012-11-04 01:59:59 CDT" Does exist, but has deceptive internal structure #' #' fit_to_timeline(tricky) #' ## Returns: #' ## [1] "2012-11-04 02:00:00 CST" instant paired with correct tz & DST combination #' ## [2] "2012-11-04 00:05:00 CDT" instant paired with correct tz & DST combination #' ## [3] NA - fake time changed to NA (compare to as.POSIXct(tricky)) #' ## [4] "2012-11-04 01:59:59 CDT" -real instant, left as is #' #' fit_to_timeline(tricky, simple = TRUE) #' ## Returns valid time-dates by extrapolating CDT and CST zones: #' ## [1] "2012-11-04 01:00:05 CST" "2012-11-04 01:05:00 CDT" #' ## [3] "2010-03-14 03:05:00 CDT" "2012-11-04 01:59:59 CDT" #' } #' @export fit_to_timeline <- function(lt, class = "POSIXct", simple = FALSE) { if (class != "POSIXlt" && class != "POSIXct") stop("class argument must be POSIXlt or POSIXct") if (simple) { if (class == "POSIXct") as.POSIXct(lt) else as.POSIXlt(as.POSIXct(lt)) } else { ## fall break - DST only changes if it has to ct <- as.POSIXct(lt) lt2 <- as.POSIXlt(ct) dstdiff <- !is.na(ct) & (lt$isdst != lt2$isdst) if (any(dstdiff)) { dlt <- lt[dstdiff] dlt2 <- lt2[dstdiff] dlt$isdst <- dlt2$isdst dlt$zone <- dlt2$zone dlt$gmtoff <- dlt2$gmtoff dct <- as.POSIXct(dlt) # should directly match if not in gap if (class == "POSIXct") ct[dstdiff] <- dct else lt2[dstdiff] <- dlt chours <- format.POSIXlt(as.POSIXlt(dct), "%H", usetz = FALSE) lhours <- format.POSIXlt(dlt, "%H", usetz = FALSE) any <- any(hdiff <- chours != lhours) if (!is.na(any) && any) { if (class == "POSIXct") ct[dstdiff][hdiff] <- NA else lt2[dstdiff][hdiff] <- NA } } if (class == "POSIXct") ct else lt2 } } lubridate/R/util.r0000644000176200001440000000731213201152061013560 0ustar liggesusersmatch_lengths <- function(x, y) { n.x <- length(x) n.y <- length(y) n.max <- max(n.x, n.y) n.min <- min(n.x, n.y) if (n.max %% n.min != 0L) { stop("longer object length is not a multiple of shorter object length") } else { if (n.x < n.y) { x <- rep(x, length.out = n.y) } else { y <- rep(y, length.out = n.x) } } list(x, y) } recognize <- function(x) { recognized <- c("POSIXt", "POSIXlt", "POSIXct", "yearmon", "yearqtr", "Date") if (all(class(x) %in% recognized)) return(TRUE) return(FALSE) } standardise_date_names <- function(x) { dates <- c("second", "minute", "hour", "mday", "wday", "yday", "day", "week", "month", "year", "tz") y <- gsub("(.)s$", "\\1", x) res <- dates[pmatch(y, dates)] if (any(is.na(res))) { stop("Invalid unit name: ", paste(x[is.na(res)], collapse = ", "), call. = FALSE) } res } standardise_difftime_names <- function(x) { dates <- c("secs", "mins", "hours", "days", "weeks") y <- gsub("(.)s$", "\\1", x) y <- substr(y, 1, 3) res <- dates[pmatch(y, dates)] if (any(is.na(res))) { stop("Invalid difftime name: ", paste(x[is.na(res)], collapse = ", "), call. = FALSE) } res } standardise_period_names <- function(x) { dates <- c("second", "minute", "hour", "day", "week", "month", "year", ## these ones are used for rounding only "bimonth", "quarter", "halfyear", "season") y <- gsub("(.)s$", "\\1", x) y <- substr(y, 1, 3) res <- dates[pmatch(y, dates)] if (any(is.na(res))) { stop("Invalid period name: ", paste(x[is.na(res)], collapse = ", "), call. = FALSE) } res } standardise_lt_names <- function(x) { if (length(x) == 0L) stop("No unit names supplied.") dates <- c("sec", "min", "hour", "day", "mday", "wday", "yday", "mon", "year", "tz") y <- gsub("(.)s$", "\\1", x) y <- substr(y, 1, 3) res <- dates[pmatch(y, dates)] if (any(is.na(res))) { stop("Invalid unit name: ", paste(x[is.na(res)], collapse = ", "), call. = FALSE) } res } ## return list(n=nr_units, unit="unit_name") parse_period_unit <- function(unit) { if (length(unit) > 1) { warning("Unit argument longer than 1. Taking first element.") unit <- unit[[1]] } p <- .Call(C_parse_period, as.character(unit)) if (!is.na(p[[1]])) { period_units <- c("second", "minute", "hour", "day", "week", "month", "year") wp <- which(p > 0) if (length(wp) > 1) { ## Fractional units are actually supported but only when it leads to one ## final unit. stop("Cannot't parse heterogenuous or fractional units larger than one minute.") } list(n = p[wp], unit = period_units[wp]) } else { ## this part is for backward compatibility and allows for bimonth, halfyear ## and quarter m <- regexpr(" *(?[0-9.,]+)? *(?[^ \t\n]+)", unit[[1]], perl = T) if (m > 0) { ## should always match nms <- attr(m, "capture.names") nms <- nms[nzchar(nms)] start <- attr(m, "capture.start") end <- start + attr(m, "capture.length") - 1L n <- if (end[[1]] >= start[[1]]) { as.integer(str_sub(unit, start[[1]], end[[1]])) } else { 1 } unit <- str_sub(unit, start[[2]], end[[2]]) list(n = n, unit = unit) } else { stop(sprintf("Invalid unit specification '%s'", unit)) } } } undefined_arithmetic <- function(e1, e2) { msg <- sprintf("Arithmetic operators undefined for '%s' and '%s' classes: convert one to numeric or a matching time-span class.", class(e1), class(e2)) stop(msg) } date_to_posix <- function(date, tz = "UTC") { utc <- .POSIXct(unclass(date) * 86400, tz = "UTC") if (tz == "UTC") utc else force_tz(utc, tz) } lubridate/R/accessors-week.r0000644000176200001440000000327613201152061015526 0ustar liggesusers#' @include periods.r NULL #' Get/set weeks component of a date-time #' #' @description #' `week()` returns the number of complete seven day periods that have #' occurred between the date and January 1st, plus one. #' @param x a date-time object. Must be a POSIXct, POSIXlt, Date, chron, #' yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, or #' fts object. #' @param value a numeric object #' @return the weeks element of x as an integer number #' @keywords utilities manip chron #' @references #' \url{http://en.wikipedia.org/wiki/ISO_week_date} #' \url{http://www.cmmcp.org/epiweek.htm} #' @seealso [isoyear()] #' @examples #' x <- ymd("2012-03-26") #' week(x) #' week(x) <- 1 #' week(x) <- 54 #' week(x) > 3 #' @export week <- function(x) (yday(x) - 1) %/% 7 + 1 #' @rdname week #' @export "week<-" <- function(x, value) x <- x + days((value - week(x)) * 7) .other_week <- function(x, week_start) { x <- as.POSIXlt(x) date <- make_date(year(x), month(x), day(x)) wday <- wday(x, week_start = week_start) date <- date + (4 - wday) jan1 <- as.numeric(make_date(year(date), 1, 1)) 1L + (as.numeric(date) - jan1) %/% 7L } #' @description `isoweek()` returns the week as it would appear in the ISO 8601 #' system, which uses a reoccurring leap week. #' @rdname week #' @export isoweek <- function(x) { .other_week(x, 1) } #' @description `epiweek()` is the US CDC version of epidemiological week. It #' follows same rules as `isoweek()` but starts on Sunday. In other parts of #' the world the convention is to start epidemiological weeks on Monday, #' which is the same as `isoweek`. #' #' @rdname week #' @export epiweek <- function(x) { .other_week(x, 7) } lubridate/R/decimal-dates.r0000644000176200001440000000344613201152061015303 0ustar liggesusers#' Converts a date to a decimal of its year #' #' @export #' @param date a POSIXt or Date object #' @return a numeric object where the date is expressed as a fraction of its year #' @keywords manip chron methods #' @examples #' date <- ymd("2009-02-10") #' decimal_date(date) # 2009.11 decimal_date <- function(date) UseMethod("decimal_date") #' @export decimal_date.default <- function(date) { if (any(!inherits(date, c("POSIXt", "POSIXct", "POSIXlt", "Date")))) stop("date(s) not in POSIXt or Date format") Y <- year(date) start <- make_datetime(Y, 1L, 1L, tz = tz(date)) end <- make_datetime(Y + 1L, 1L, 1L, tz = tz(date)) sofar <- as.numeric(difftime(date, start, units = "secs")) total <- as.numeric(difftime(end, start, units = "secs")) Y + sofar/total } #' @export decimal_date.zoo <- function(date) decimal_date(zoo::index(date)) ## #' @export ## decimal_date.its <- function(date) ## decimal_date.default(attr(date, "dates")) #' Converts a decimal to a date #' #' @export #' @param decimal a numeric object #' @param tz the time zone required #' @return a POSIXct object, whose year corresponds to the integer part of #' decimal. The months, days, hours, minutes and seconds elements are picked so #' the date-time will accurately represent the fraction of the year expressed by #' decimal. #' @keywords manip chron methods #' @examples #' date <- ymd("2009-02-10") #' decimal <- decimal_date(date) # 2009.11 #' date_decimal(decimal) # "2009-02-10 UTC" date_decimal <- function(decimal, tz = "UTC") { Y <- trunc(decimal) ## parsing is much faster than updating start <- make_datetime(Y, 1L, 1L, tz = tz) end <- make_datetime(Y + 1L, 1L, 1L, tz = tz) seconds <- as.numeric(difftime(end, start, units = "secs")) frac <- decimal - Y end <- start + seconds*frac return(end) } lubridate/R/numeric.r0000644000176200001440000000002713102102352014237 0ustar liggesuserssetOldClass("numeric") lubridate/R/instants.r0000644000176200001440000001011713201152061014443 0ustar liggesusers#' Is x a date-time object? #' #' An instant is a specific moment in time. Most common date-time #' objects (e.g, POSIXct, POSIXlt, and Date objects) are instants. #' #' @aliases instant instants #' @export #' @param x an R object #' @return TRUE if x is a POSIXct, POSIXlt, or Date object, FALSE otherwise. #' @seealso [is.timespan()], [is.POSIXt()], [is.Date()] #' @keywords logic chron #' @examples #' is.instant(as.Date("2009-08-03")) # TRUE #' is.timepoint(5) # FALSE is.instant <- function(x) inherits(x, c("POSIXt", "POSIXct", "POSIXlt", "Date")) #' @export #' @rdname is.instant is.timepoint <- is.instant #' The current time #' #' @param tzone a character vector specifying which time zone you would like #' the current time in. tzone defaults to your computer's system timezone. #' You can retrieve the current time in the Universal Coordinated Time (UTC) #' with now("UTC"). #' @return the current date and time as a POSIXct object #' #' @seealso [here()] #' #' @keywords chron utilities #' @examples #' now() #' now("GMT") #' now("") #' now() == now() # would be TRUE if computer processed both at the same instant #' now() < now() # TRUE #' now() > now() # FALSE #' @export now <- function(tzone = "") with_tz(Sys.time(), tzone) #' The current date #' #' @param tzone a character vector specifying which time zone you would like to #' find the current date of. tzone defaults to the system time zone set on your #' computer. #' @return the current date as a Date object #' #' @keywords chron utilities #' @examples #' today() #' today("GMT") #' today() == today("GMT") # not always true #' today() < as.Date("2999-01-01") # TRUE (so far) #' @export today <- function(tzone = "") { as_date(now(tzone)) } #' 1970-01-01 UTC #' #' Origin is the date-time for 1970-01-01 UTC in POSIXct format. This date-time #' is the origin for the numbering system used by POSIXct, POSIXlt, chron, and #' Date classes. #' #' @keywords data chron #' @examples #' origin #' @export origin origin <- structure(0, class = c("POSIXct", "POSIXt"), tzone = "UTC") .rep_maybe <- function(x, N) { if (N > 1 && length(x) > 1 && length(x) != N) { out <- rep_len(x, N) ## repl_len doesn't preserve attributes if (is.POSIXct(x)) attributes(out) <- attributes(x) out } else { x } } ##' Efficient creation of date-times from numeric representations ##' ##' `make_datetime()` is a very fast drop-in replacement for ##' [base::ISOdate()] and [base::ISOdatetime()]. `make_date()` produces ##' objects of class `Date`. ##' ##' Input vectors are silently recycled. All inputs except `sec` are ##' silently converted to integer vectors; `sec` can be either integer or ##' double. ##' ##' @param year numeric year ##' @param month numeric month ##' @param day numeric day ##' @param hour numeric hour ##' @param min numeric minute ##' @param sec numeric second ##' @param tz time zone. Defaults to UTC. ##' @export ##' @examples ##' make_datetime(year = 1999, month = 12, day = 22, sec = 10) ##' make_datetime(year = 1999, month = 12, day = 22, sec = c(10, 11)) make_datetime <- function(year = 1970L, month = 1L, day = 1L, hour = 0L, min = 0L, sec = 0, tz = "UTC") { lengths <- vapply(list(year, month, day, hour, min, sec), length, 1, USE.NAMES = FALSE) if (min(lengths) == 0L) { .POSIXct(numeric(), tz = tz) } else { N <- max(lengths) C_update_dt(.rep_maybe(origin, N), year = .rep_maybe(year, N), month = .rep_maybe(month, N), yday = integer(), mday = .rep_maybe(day, N), wday = integer(), hour = .rep_maybe(hour, N), minute = .rep_maybe(min, N), second = .rep_maybe(sec, N), tz = tz) } } ##' @rdname make_datetime ##' @export make_date <- function(year = 1970L, month = 1L, day = 1L) { lengths <- vapply(list(year, month, day), length, 1, USE.NAMES = FALSE) if (min(lengths) == 0L) { as.Date(integer(), origin = origin) } else { N <- max(lengths) secs <- .Call(C_make_d, rep_len(as.integer(year), N), rep_len(as.integer(month), N), rep_len(as.integer(day), N)) structure(secs/86400L, class = "Date") } } lubridate/R/round.r0000644000176200001440000002721113263104313013737 0ustar liggesusers#' Round, floor and ceiling methods for date-time objects #' #' @description #' Rounding to the nearest unit or multiple of a unit are supported. All #' meaningfull specifications in English language are supported - secs, min, #' mins, 2 minutes, 3 years etc. #' #' Rounding to fractional seconds is supported. Please note that rounding to #' fractions smaller than 1s can lead to large precision errors due to the #' floating point representation of the POSIXct objects. See examples. #' #' `round_date()` takes a date-time object and rounds it to the nearest value #' of the specified time unit. For rounding date-times which is exactly halfway #' between two consecutive units, the convention is to round up. Note that this #' is in line with the behavior of R's [base::round.POSIXt()] function #' but does not follow the convention of the base [base::round()] function #' which "rounds to the even digit" per IEC 60559. #' #' @details In \pkg{lubridate}, rounding of a date-time objects tries to #' preserve the class of the input object whenever possible. This is done by #' first rounding to an instant and then converting to the original class by #' usual R conventions. #' #' #' @section Rounding Up Date Objects: #' #' By default rounding up `Date` objects follows 3 steps: #' #' 1. Convert to an instant representing lower bound of the Date: #' `2000-01-01` --> `2000-01-01 00:00:00` #' #' 2. Round up to the \strong{next} closest rounding unit boundary. For example, #' if the rounding unit is `month` then next closest boundary of `2000-01-01` #' is `2000-02-01 00:00:00`. #' #' The motivation for this is that the "partial" `2000-01-01` is conceptually #' an interval (`2000-01-01 00:00:00` -- `2000-01-02 00:00:00`) and the day #' hasn't started clocking yet at the exact boundary `00:00:00`. Thus, it #' seems wrong to round up a day to its lower boundary. #' #' The behavior on the boundary can be changed by setting #' `change_on_boundary` to a non-`NULL` value. #' #' 3. If rounding unit is smaller than a day, return the instant from step 2 #' (`POSIXct`), otherwise convert to and return a `Date` object. #' #' @rdname round_date #' @param x a vector of date-time objects #' @param unit a character string specifying a time unit or a multiple of a unit #' to be rounded to. Valid base units are `second`, `minute`, `hour`, `day`, #' `week`, `month`, `bimonth`, `quarter`, `season`, `halfyear` and #' `year`. Arbitrary unique English abbreviations as in the [period()] #' constructor are allowed. Rounding to multiple of units (except weeks) is #' supported. #' @param change_on_boundary If NULL (the default) don't change instants on the #' boundary (`ceiling_date(ymd_hms('2000-01-01 00:00:00'))` is `2000-01-01 #' 00:00:00`), but round up `Date` objects to the next boundary #' (`ceiling_date(ymd("2000-01-01"), "month")` is `"2000-02-01"`). When #' `TRUE`, instants on the boundary are rounded up to the next boundary. When #' `FALSE`, date-time on the boundary are never rounded up (this was the #' default for \pkg{lubridate} prior to `v1.6.0`. See section `Rounding Up #' Date Objects` below for more details. #' @param week_start when unit is `weeks` specify the reference day; 7 being Sunday. #' @keywords manip chron #' @seealso [base::round()] #' @examples #' #' ## print fractional seconds #' options(digits.secs=6) #' #' x <- ymd_hms("2009-08-03 12:01:59.23") #' round_date(x, ".5s") #' round_date(x, "sec") #' round_date(x, "second") #' round_date(x, "minute") #' round_date(x, "5 mins") #' round_date(x, "hour") #' round_date(x, "2 hours") #' round_date(x, "day") #' round_date(x, "week") #' round_date(x, "month") #' round_date(x, "bimonth") #' round_date(x, "quarter") == round_date(x, "3 months") #' round_date(x, "halfyear") #' round_date(x, "year") #' #' x <- ymd_hms("2009-08-03 12:01:59.23") #' floor_date(x, ".1s") #' floor_date(x, "second") #' floor_date(x, "minute") #' floor_date(x, "hour") #' floor_date(x, "day") #' floor_date(x, "week") #' floor_date(x, "month") #' floor_date(x, "bimonth") #' floor_date(x, "quarter") #' floor_date(x, "season") #' floor_date(x, "halfyear") #' floor_date(x, "year") #' #' x <- ymd_hms("2009-08-03 12:01:59.23") #' ceiling_date(x, ".1 sec") # imprecise representation at 0.1 sec !!! #' ceiling_date(x, "second") #' ceiling_date(x, "minute") #' ceiling_date(x, "5 mins") #' ceiling_date(x, "hour") #' ceiling_date(x, "day") #' ceiling_date(x, "week") #' ceiling_date(x, "month") #' ceiling_date(x, "bimonth") == ceiling_date(x, "2 months") #' ceiling_date(x, "quarter") #' ceiling_date(x, "season") #' ceiling_date(x, "halfyear") #' ceiling_date(x, "year") #' #' ## As of R 3.4.2 POSIXct printing of fractional numbers is wrong #' as.POSIXct("2009-08-03 12:01:59.3") ## -> "2009-08-03 12:01:59.2 CEST" #' ceiling_date(x, ".1 sec") ## -> "2009-08-03 12:01:59.2 CEST" #' #' @export round_date <- function(x, unit = "second", week_start = getOption("lubridate.week.start", 7)) { if (!length(x)) return(x) parsed_unit <- parse_period_unit(unit) n <- parsed_unit$n basic_unit <- standardise_period_names(parsed_unit$unit) new <- if (n == 1 && basic_unit %in% c("second", "minute", "hour", "day")) { ## special case for fast rounding round.POSIXt(x, units = lub2base_units[[basic_unit]]) } else { above <- unclass(as.POSIXct(ceiling_date(x, unit))) mid <- unclass(as.POSIXct(x)) below <- unclass(as.POSIXct(floor_date(x, unit))) wabove <- (above - mid) <= (mid - below) wabove <- !is.na(wabove) & wabove new <- below new[wabove] <- above[wabove] .POSIXct(new, tz = tz(x)) } reclass_date(new, x) } reclass_date_maybe <- function(new, orig, unit) { if (is.Date(orig) && !unit %in% c("day", "week", "month", "year")) as.POSIXct(new) else reclass_date(new, orig) } #' @description #' `floor_date()` takes a date-time object and rounds it down to the nearest #' boundary of the specified time unit. #' @rdname round_date #' @export floor_date <- function(x, unit = "seconds", week_start = getOption("lubridate.week.start", 7)) { if (!length(x)) return(x) parsed_unit <- parse_period_unit(unit) n <- parsed_unit$n unit <- standardise_period_names(parsed_unit$unit) if (unit %in% c("second", "minute", "hour", "day")) { out <- trunc_multi_unit(x, unit, n) reclass_date_maybe(out, x, unit) } else { if (n > 1 && unit == "week") { ## fixme: warning("Multi-unit not supported for weeks. Ignoring.") } if (unit %in% c("bimonth", "quarter", "halfyear", "season") || (n > 1 && unit == "month")) { new_months <- switch(unit, month = floor_multi_unit1(month(x), n), bimonth = floor_multi_unit1(month(x), 2 * n), quarter = floor_multi_unit1(month(x), 3 * n), halfyear = floor_multi_unit1(month(x), 6 * n), season = floor_multi_unit(month(x), 3 * n)) n <- Inf unit <- "month" } switch(unit, week = update(x, wdays = 1, hours = 0, minutes = 0, seconds = 0, week_start = week_start), month = { if (n > 1) update(x, months = new_months, mdays = 1, hours = 0, minutes = 0, seconds = 0) else update(x, mdays = 1, hours = 0, minutes = 0, seconds = 0) }, year = { ## due to bug https://github.com/hadley/lubridate/issues/319 we ## need to do it in two steps if (n > 1) { y <- update(x, ydays = 1, hours = 0, minutes = 0, seconds = 0) update(y, years = floor_multi_unit(year(y), n)) } else { update(x, ydays = 1, hours = 0, minutes = 0, seconds = 0) } }) } } #' @description #' `ceiling_date()` takes a date-time object and rounds it up to the nearest #' boundary of the specified time unit. #' @rdname round_date #' @export #' @examples #' x <- ymd("2000-01-01") #' ceiling_date(x, "month") #' ceiling_date(x, "month", change_on_boundary = TRUE) ceiling_date <- function(x, unit = "seconds", change_on_boundary = NULL, week_start = getOption("lubridate.week.start", 7)) { if (!length(x)) return(x) parsed_unit <- parse_period_unit(unit) n <- parsed_unit$n unit <- standardise_period_names(parsed_unit$unit) if (is.null(change_on_boundary)) { change_on_boundary <- is.Date(x) } if (unit == "second") { sec <- second(x) csec <- ceil_multi_unit(sec, n) if (!change_on_boundary) { wsec <- which(csec - n == sec) if (length(wsec)) csec[wsec] <- sec[wsec] } update(x, seconds = csec, simple = T) } else if (unit %in% c("minute", "hour")) { ## cannot use this for minute/hour for Date class; local tz interferes with ## the computation new <- as_datetime(x, tz = tz(x)) delta <- switch(unit, minute = 60, hour = 3600, day = 86400) * n new <- if (change_on_boundary) { trunc_multi_unit(new, unit, n) + delta } else { new1 <- trunc_multi_unit(new, unit, n) not_same <- which(new1 != new) new1[not_same] <- new1[not_same] + delta new1 } reclass_date_maybe(new, x, unit) } else { if (n > 1 && unit == "week") { warning("Multi-unit not supported for weeks. Ignoring.") } ## need this to accomodate the case when date is on a boundary new <- if (change_on_boundary) x else update(x, seconds = second(x) - 0.00001, simple = T) if (unit %in% c("month", "bimonth", "quarter", "halfyear", "season")) { new_month <- switch(unit, month = ceil_multi_unit1(month(new), n), bimonth = ceil_multi_unit1(month(new), 2 * n), quarter = ceil_multi_unit1(month(new), 3 * n), halfyear = ceil_multi_unit1(month(new), 6 * n), season = ceil_multi_unit(month(new), 3 * n)) unit <- "month" } new <- switch(unit, minute = update(new, minute = ceil_multi_unit(minute(new), n), second = 0, simple = T), hour = update(new, hour = ceil_multi_unit(hour(new), n), minute = 0, second = 0, simple = T), day = update(new, day = ceil_multi_unit1(day(new), n), hour = 0, minute = 0, second = 0), week = update(new, wday = 8, hour = 0, minute = 0, second = 0, week_start = week_start), month = update(new, months = new_month, mdays = 1, hours = 0, minutes = 0, seconds = 0), year = update(new, year = ceil_multi_unit(year(new), n), month = 1, mday = 1, hour = 0, minute = 0, second = 0)) reclass_date_maybe(new, x, unit) } } trunc_multi_limits <- c(second = 60L, minute = 60L, hour = 24, day = 31) trunc_multi_unit <- function(x, unit, n) { x <- as.POSIXlt(x) if (n > trunc_multi_limits[[unit]]) stop(sprintf("Rounding with %s > %d is not supported", unit, trunc_multi_limits[[unit]])) switch(unit, second = { x$sec <- if (n == 1) trunc(x$sec) else floor_multi_unit(x$sec, n) }, minute = { x$sec[] <- 0 x$min <- floor_multi_unit(x$min, n) }, hour = { x$sec[] <- 0 x$min[] <- 0L x$hour <- floor_multi_unit(x$hour, n) }, day = { x$sec[] <- 0 x$min[] <- 0L x$hour[] <- 0L x$isdst[] <- -1L x$mday <- floor_multi_unit1(x$mday, n) }, stop("Invalid unit ", unit)) x } floor_multi_unit <- function(x, n) { (x %/% n) * n } floor_multi_unit1 <- function(x, n) { (((x - 1) %/% n) * n) + 1L } ceil_multi_unit <- function(x, n) { (x %/% n) * n + n } ceil_multi_unit1 <- function(x, n) { (((x - 1) %/% n) * n) + n + 1L } lubridate/R/parse.r0000644000176200001440000011104713263145001013722 0ustar liggesusers##' Parse dates with **y**ear, **m**onth, and **d**ay components ##' ##' Transforms dates stored in character and numeric vectors to Date or POSIXct ##' objects (see `tz` argument). These functions recognize arbitrary ##' non-digit separators as well as no separator. As long as the order of ##' formats is correct, these functions will parse dates correctly even when the ##' input vectors contain differently formatted dates. See examples. ##' ##' In case of heterogeneous date formats `ymd()` family guesses formats based ##' on a sub-set of the input vector. If the input vector contains many missing ##' values or non-date strings, the sub-set might not contain meaningful dates ##' and the date-time format won't be guessed resulting in ##' "All formats failed to parse" error. In such cases please see ##' [parse_date_time()] for a more flexible parsing interface. ##' ##' If the `truncated` parameter is non-zero, the `ymd` functions also check for ##' truncated formats. For example `ymd()` with `truncated = 2` will also ##' parse incomplete dates like `2012-06` and `2012`. ##' ##' NOTE: The `ymd` family of functions are based on `parse_date_time()` and thus ##' directly drop to the internal C parser for numeric months, but use R's ##' `strptime()` for alphabetic months. This implies that some of the `strptime()`'s ##' limitations are inherited by \pkg{lubridate}'s parser. For example, truncated ##' formats (like \code{\%Y-\%b}) will not be parsed. Numeric truncated formats (like ##' \code{\%Y-\%m}) are handled correctly by \pkg{lubridate}'s C parser. ##' ##' As of version 1.3.0, \pkg{lubridate}'s parse functions no longer return a ##' message that displays which format they used to parse their input. You can ##' change this by setting the `lubridate.verbose` option to `TRUE` with ##' `options(lubridate.verbose = TRUE)`. ##' ##' @export ##' @param ... a character or numeric vector of suspected dates ##' @param quiet logical. When TRUE function evalueates without displaying ##' customary messages. ##' @param tz Time zone indicator. If NULL (default) a Date object is ##' returned. Otherwise a POSIXct with time zone attribute set to `tz`. ##' @param locale locale to be used, see [locales]. On linux systems you ##' can use `system("locale -a")` to list all the installed locales. ##' @param truncated integer. Number of formats that can be truncated. ##' @return a vector of class POSIXct if tz argument is non-NULL or Date if tz ##' is NULL (default) ##' @seealso [parse_date_time()] for an even more flexible low level ##' mechanism. ##' @keywords chron ##' @examples ##' x <- c("09-01-01", "09-01-02", "09-01-03") ##' ymd(x) ##' x <- c("2009-01-01", "2009-01-02", "2009-01-03") ##' ymd(x) ##' ymd(090101, 90102) ##' now() > ymd(20090101) ##' ## TRUE ##' dmy(010210) ##' mdy(010210) ##' ##' ## heterogenuous formats in a single vector: ##' x <- c(20090101, "2009-01-02", "2009 01 03", "2009-1-4", ##' "2009-1, 5", "Created on 2009 1 6", "200901 !!! 07") ##' ymd(x) ##' ##' ## What lubridate might not handle: ##' ##' ## Extremely weird cases when one of the separators is "" and some of the ##' ## formats are not in double digits might not be parsed correctly: ##' \dontrun{ymd("201002-01", "201002-1", "20102-1") ##' dmy("0312-2010", "312-2010")} ymd <- function(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx(..., orders = "ymd", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd ydm <- function(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx(..., orders = "ydm", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd mdy <- function(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx(..., orders = "mdy", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd myd <- function(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx(..., orders = "myd", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd dmy <- function(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx(..., orders = "dmy", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd dym <- function(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx(..., orders = "dym", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd yq <- function(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME")) .parse_xxx(..., orders = "yq", quiet = quiet, tz = tz, locale = locale, truncated = 0) ##' Parse date-times with **y**ear, **m**onth, and **d**ay, **h**our, ##' **m**inute, and **s**econd components. ##' ##' Transform dates stored as character or numeric vectors to POSIXct ##' objects. ymd_hms family of functions recognize all non-alphanumeric ##' separators (with the exception of "." if `frac = TRUE`) and correctly ##' handle heterogeneous date-time representations. For more flexibility in ##' treatment of heterogeneous formats, see low level parser ##' [parse_date_time()]. ##' ##' ymd_hms() functions automatically assigns the Universal Coordinated Time ##' Zone (UTC) to the parsed date. This time zone can be changed with ##' [force_tz()]. ##' ##' The most common type of irregularity in date-time data is the truncation ##' due to rounding or unavailability of the time stamp. If the `truncated` ##' parameter is non-zero, the `ymd_hms` functions also check for truncated ##' formats. For example, `ymd_hms()` with `truncated = 3` will also parse ##' incomplete dates like `2012-06-01 12:23`, `2012-06-01 12` and ##' `2012-06-01`. NOTE: The `ymd` family of functions are based on ##' [strptime()] which currently fails to parse \code{\%y-\%m} formats. ##' ##' In case of heterogeneous date formats `ymd_hms()` family guesses formats ##' based on a sub-set of the input vector. If the input vector contains many ##' missing values or non-date strings, the sub-set might not contain meaningful ##' dates and the date-time format won't be guessed resulting in ##' "All formats failed to parse" error. In such cases please see ##' [parse_date_time()] for a more flexible parsing interface. ##' ##' As of version 1.3.0, \pkg{lubridate}'s parse functions no longer return a ##' message that displays which format they used to parse their input. You can ##' change this by setting the `lubridate.verbose` option to `TRUE` with ##' `options(lubridate.verbose = TRUE)`. ##' ##' @export ##' @param ... a character vector of dates in year, month, day, hour, minute, ##' second format ##' @param quiet logical. When TRUE function evalueates without displaying customary messages. ##' @param tz a character string that specifies which time zone to parse the date with. The string ##' must be a time zone that is recognized by the user's OS. ##' @param locale locale to be used, see \link{locales}. On linux systems you ##' can use `system("locale -a")` to list all the installed locales. ##' @param truncated integer, indicating how many formats can be missing. See details. ##' @return a vector of [POSIXct] date-time objects ##' @seealso ##' - [ymd()], [hms()] ##' - [parse_date_time()] for the underlying mechanism ##' @keywords POSIXt parse ##' @examples ##' ##' x <- c("2010-04-14-04-35-59", "2010-04-01-12-00-00") ##' ymd_hms(x) ##' x <- c("2011-12-31 12:59:59", "2010-01-01 12:00:00") ##' ymd_hms(x) ##' ##' ##' ## ** heterogenuous formats ** ##' x <- c(20100101120101, "2009-01-02 12-01-02", "2009.01.03 12:01:03", ##' "2009-1-4 12-1-4", ##' "2009-1, 5 12:1, 5", ##' "200901-08 1201-08", ##' "2009 arbitrary 1 non-decimal 6 chars 12 in between 1 !!! 6", ##' "OR collapsed formats: 20090107 120107 (as long as prefixed with zeros)", ##' "Automatic wday, Thu, detection, 10-01-10 10:01:10 and p format: AM", ##' "Created on 10-01-11 at 10:01:11 PM") ##' ymd_hms(x) ##' ##' ## ** fractional seconds ** ##' op <- options(digits.secs=3) ##' dmy_hms("20/2/06 11:16:16.683") ##' options(op) ##' ##' ## ** different formats for ISO8601 timezone offset ** ##' ymd_hms(c("2013-01-24 19:39:07.880-0600", ##' "2013-01-24 19:39:07.880", "2013-01-24 19:39:07.880-06:00", ##' "2013-01-24 19:39:07.880-06", "2013-01-24 19:39:07.880Z")) ##' ##' ## ** internationalization ** ##' \dontrun{ ##' x_RO <- "Ma 2012 august 14 11:28:30 " ##' ymd_hms(x_RO, locale = "ro_RO.utf8") ##' } ##' ##' ## ** truncated time-dates ** ##' x <- c("2011-12-31 12:59:59", "2010-01-01 12:11", "2010-01-01 12", "2010-01-01") ##' ymd_hms(x, truncated = 3) ##' x <- c("2011-12-31 12:59", "2010-01-01 12", "2010-01-01") ##' ymd_hm(x, truncated = 2) ##' ## ** What lubridate might not handle ** ##' ## Extremely weird cases when one of the separators is "" and some of the ##' ## formats are not in double digits might not be parsed correctly: ##' \dontrun{ ##' ymd_hm("20100201 07-01", "20100201 07-1", "20100201 7-01")} ##' ymd_hms <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0){ .parse_xxx_hms(..., orders = c("ymdTz", "ymdT"), quiet = quiet, tz = tz, locale = locale, truncated = truncated) } #' @export #' @rdname ymd_hms ymd_hm <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = "ymdR", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms ymd_h <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = "ymdr", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms dmy_hms <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = c("dmyTz", "dmyT"), quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms dmy_hm <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = "dmyR", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms dmy_h <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = "dmyr", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms mdy_hms <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = c("mdyTz", "mdyT"), quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms mdy_hm <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = "mdyR", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms mdy_h <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = "mdyr", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms ydm_hms <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = c("ydmTz", "ydmT"), quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms ydm_hm <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = "ydmR", quiet = quiet, tz = tz, locale = locale, truncated = truncated) #' @export #' @rdname ymd_hms ydm_h <- function(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) .parse_xxx_hms(..., orders = "ydmr", quiet = quiet, tz = tz, locale = locale, truncated = truncated) ##' @rdname hms ##' @examples ##' ms(c("09:10", "09:02", "1:10")) ##' ms("7 6") ##' ms("6,5") ##' @export ms <- function(..., quiet = FALSE, roll = FALSE) { out <- .parse_hms(..., order = "MS", quiet = quiet) if (roll) { hms <- .roll_hms(min = out["M", ], sec = out["S", ]) period(hour = hms$hour, minute = hms$min, second = hms$sec) } else { period(minute = out["M", ], second = out["S", ]) } } ##' @rdname hms ##' @examples ##' hm(c("09:10", "09:02", "1:10")) ##' hm("7 6") ##' hm("6,5") ##' @export hm <- function(..., quiet = FALSE, roll = FALSE) { out <- .parse_hms(..., order = "HM", quiet = quiet) if (roll) { hms <- .roll_hms(hour = out["H", ], min = out["M", ]) period(hour = hms$hour, minute = hms$min, second = hms$sec) } else { period(hour = out["H", ], minute = out["M", ]) } } ##' Parse periods with **h**our, **m**inute, and **s**econd components ##' ##' Transforms a character or numeric vector into a period object with the ##' specified number of hours, minutes, and seconds. hms() recognizes all ##' non-numeric characters except '-' as separators ('-' is used for negative ##' durations). After hours, minutes and seconds have been parsed, the ##' remaining input is ignored. ##' ##' @param ... a character vector of hour minute second triples ##' @param quiet logical. When TRUE function evalueates without displaying ##' customary messages. ##' @param roll logical. When TRUE, smaller units are rolled over to higher units ##' if they exceed the conventional limit. For example, ##' `hms("01:59:120", roll=TRUE)` produces period "2H 1M 0S". ##' @return a vector of period objects ##' @seealso [hm()], [ms()] ##' @keywords period ##' @examples ##' ##' x <- c("09:10:01", "09:10:02", "09:10:03") ##' hms(x) ##' ##' hms("7 6 5", "3:23:::2", "2 : 23 : 33", "Finished in 9 hours, 20 min and 4 seconds") ##' @export hms <- function(..., quiet = FALSE, roll = FALSE) { out <- .parse_hms(..., order = "HMS", quiet = quiet) if (roll) { hms <- .roll_hms(out["H", ], out["M", ], out["S", ]) period(hour = hms$hour, minute = hms$min, second = hms$sec) } else { period(hour = out["H", ], minute = out["M", ], second = out["S", ]) } } .roll_hms <- function(hour = 0, min = 0, sec = 0){ min <- min + sec %/% 60 sec <- sec %% 60 hour <- hour + min %/% 60 min <- min %% 60 list(hour = hour, min = min, sec = sec) } .parse_hms <- function(..., order, quiet = FALSE) { ## wraper for C level parse_hms hms <- unlist(lapply(list(...), .num_to_date), use.names= FALSE) out <- matrix(.Call(C_parse_hms, hms, order), nrow = 3L, dimnames = list(c("H", "M", "S"), NULL)) if (!quiet) { ## fixme: this warning should be dropped to C and thrown only when there are ## real parsing errors #530 if (any(is.na(out[substr(order, ln <- nchar(order), ln), ]))) warning("Some strings failed to parse, or all strings are NAs") } out } ##' User friendly date-time parsing functions ##' ##' `parse_date_time()` parses an input vector into POSIXct date-time ##' object. It differs from [base::strptime()] in two respects. First, ##' it allows specification of the order in which the formats occur without the ##' need to include separators and \code{\%} prefix. Such a formating argument is ##' refered to as "order". Second, it allows the user to specify several ##' format-orders to handle heterogeneous date-time character ##' representations. ##' ##' When several format-orders are specified, `parse_date_time()` selects ##' (guesses) format-orders based on a training sub-set of the input ##' strings. After guessing the formats are ordered according to the performance ##' on the training set and applied recursively on the entire input vector. You ##' can disable training with `train=FALSE`. ##' ##' `parse_date_time()`, and all derived functions, such as `ymd_hms()`, ##' `ymd()` etc, will drop into `fast_strptime()` instead of ##' `strptime()` whenever the guessed from the input data formats are all ##' numeric. ##' ##' The list below contains formats recognized by \pkg{lubridate}. For numeric formats ##' leading 0s are optional. As compared to base `strptime()`, some of the ##' formats are new or have been extended for efficiency reasons. These formats ##' are marked with "*". The fast parsers `parse_date_time2()` and ##' `fast_strptime()` accept only formats marked with "!". ##' ##' ##' \describe{ \item{`a`}{Abbreviated weekday name in the current ##' locale. (Also matches full name)} ##' ##' \item{`A`}{Full weekday name in the current locale. (Also matches ##' abbreviated name). ##' ##' You don't need to specify `a` and `A` formats explicitly. Wday is ##' automatically handled if `preproc_wday = TRUE`} ##' ##' \item{`b`!}{Abbreviated or full month name in the current locale. The C ##' parser currently understands only English month names.} ##' ##' \item{`B`!}{Same as b.} ##' ##' \item{`d`!}{Day of the month as decimal number (01--31 or 0--31)} ##' ##' \item{`H`!}{Hours as decimal number (00--24 or 0--24).} ##' ##' \item{`I`!}{Hours as decimal number (01--12 or 1--12).} ##' ##' \item{`j`}{Day of year as decimal number (001--366 or 1--366).} ##' ##' \item{`q`!*}{Quarter (1--4). The quarter month is added to the parsed month ##' if `m` format is present.} ##' ##' \item{`m`!*}{Month as decimal number (01--12 or 1--12). For ##' `parse_date_time`. As a \pkg{lubridate} extension, also ##' matches abbreviated and full months names as `b` and ##' `B` formats. C parser understands only English month ##' names.} ##' ##' \item{`M`!}{Minute as decimal number (00--59 or 0--59).} ##' ##' \item{`p`!}{AM/PM indicator in the locale. Normally used in conjunction ##' with `I` and \bold{not} with `H`. But the \pkg{lubridate} ##' C parser accepts H format as long as hour is not greater ##' than 12. C parser understands only English locale AM/PM ##' indicator.} ##' ##' \item{`S`!}{Second as decimal number (00--61 or 0--61), allowing for up ##' to two leap-seconds (but POSIX-compliant implementations will ignore leap ##' seconds).} ##' ##' \item{`OS`}{Fractional second.} ##' ##' \item{`U`}{Week of the year as decimal number (00--53 or 0--53) using ##' Sunday as the first day 1 of the week (and typically with the first Sunday ##' of the year as day 1 of week 1). The US convention.} ##' ##' \item{`w`}{Weekday as decimal number (0--6, Sunday is 0).} ##' ##' \item{`W`}{Week of the year as decimal number (00--53 or 0--53) using ##' Monday as the first day of week (and typically with the first Monday of the ##' year as day 1 of week 1). The UK convention.} ##' ##' \item{`y`!*}{Year without century (00--99 or 0--99). In ##' `parse_date_time()` also matches year with century (Y format).} ##' ##' \item{`Y`!}{Year with century.} ##' ##' \item{`z`!*}{ISO8601 signed offset in hours and minutes from UTC. For ##' example `-0800`, `-08:00` or `-08`, all represent 8 hours ##' behind UTC. This format also matches the Z (Zulu) UTC indicator. Because ##' strptime doesn't fully support ISO8601 this format is implemented as an ##' union of 4 orders: Ou (Z), Oz (-0800), OO (-08:00) and Oo (-08). You can use ##' these four orders as any other but it is rarely ##' necessary. `parse_date_time2()` and `fast_strptime()` support all of ##' the timezone formats.} ##' ##' \item{`Om`!*}{Matches numeric month and English alphabetic months ##' (Both, long and abbreviated forms).} ##' ##' \item{`Op`!*}{Matches AM/PM English indicator.} ##' ##' \item{`r`*}{Matches `Ip` and `H` orders.} ##' ##' \item{`R`*}{Matches `HM` and`IMp` orders.} ##' ##' \item{`T`*}{Matches `IMSp`, `HMS`, and `HMOS` orders.} ##' } ##' ##' ##' @export ##' @param x a character or numeric vector of dates ##' @param orders a character vector of date-time formats. Each order string is ##' series of formatting characters as listed [base::strptime()] but might not ##' include the "\%" prefix, for example "ymd" will match all the possible ##' dates in year, month, day order. Formatting orders might include ##' arbitrary separators. These are discarded. See details for implemented ##' formats. ##' @param tz a character string that specifies the time zone with which to ##' parse the dates ##' @param truncated integer, number of formats that can be missing. The most ##' common type of irregularity in date-time data is the truncation due to ##' rounding or unavailability of the time stamp. If the `truncated` parameter ##' is non-zero `parse_date_time()` also checks for truncated formats. For ##' example, if the format order is "ymdHMS" and `truncated = 3`, ##' `parse_date_time()` will correctly parse incomplete dates like `2012-06-01 ##' 12:23`, `2012-06-01 12` and `2012-06-01`. \bold{NOTE:} The `ymd` family of ##' functions are based on `strptime()` which currently fails to parse ##' \code{\%Y-\%m} formats. ##' @param quiet logical. When TRUE progress messages are not printed, and ##' "no formats found" error is surpresed and the function simply returns a ##' vector of NAs. This mirrors the behavior of base R functions `strptime()` ##' and `as.POSIXct()`. Default is `FALSE`. ##' @param locale locale to be used, see \link{locales}. On linux systems you ##' can use `system("locale -a")` to list all the installed locales. ##' @param select_formats A function to select actual formats for parsing from a ##' set of formats which matched a training subset of `x`. It receives a named ##' integer vector and returns a character vector of selected formats. Names ##' of the input vector are formats (not orders) that matched the training ##' set. Numeric values are the number of dates (in the training set) that ##' matched the corresponding format. You should use this argument if the ##' default selection method fails to select the formats in the right ##' order. By default the formats with most formating tokens (\%) are ##' selected and \%Y counts as 2.5 tokens (so that it has a priority over ##' \%y\%m). See examples. ##' @param exact logical. If `TRUE`, the `orders` parameter is interpreted as an ##' exact `strptime()` format and no training or guessing are performed ##' (i.e. `train`, `drop` parameters are irrelevant). ##' @param train logical, default TRUE. Whether to train formats on a subset of ##' the input vector. The result of this is that supplied orders are sorted ##' according to performance on this training set, which commonly results in ##' increased performance. Please note that even when `train` is `FALSE` (and ##' `exact` is `FALSE`) guessing of the actual formats is still performed on a ##' pseudo-random subset of the original input vector. This might result in ##' `All formats failed to parse` error. See notes below. ##' @param drop logical, default FALSE. Whether to drop formats that didn't ##' match on the training set. If FALSE, unmatched on the training set formats ##' are tried as a last resort at the end of the parsing queue. Applies only ##' when `train=TRUE`. Seating this parameter to TRUE might slightly speed up ##' parsing in situations involving many formats. Prior to v1.7.0 this ##' parameter was implicitly TRUE, which resulted in occasional surprising ##' behavior when rare patterns where not present in the training set. ##' @return a vector of POSIXct date-time objects ##' @seealso `strptime()`, [ymd()], [ymd_hms()] ##' @keywords chron ##' @note `parse_date_time()` (and the derivatives `ymd()`, `ymd_hms()` etc) ##' rely on a sparse guesser that takes at most 501 elements from the supplied ##' character vector in order to identify appropriate formats from the ##' supplied orders. If you get the error `All formats failed to parse` and ##' you are confident that your vector contains valid dates, you should either ##' set `exact` argument to TRUE or use functions that don't perform format ##' guessing (`fast_strptime()`, `parse_date_time2()` or `strptime()`). ##' @note For performance reasons, when timezone is not UTC, ##' `parse_date_time2()` and `fast_strptime()` perform no validity checks for ##' daylight savings time. Thus, if your input string contains an invalid date ##' time which falls into DST gap and `lt = TRUE` you will get an `POSIXlt` ##' object with a non-existen time. If `lt = FALSE` your time instant will be ##' adjusted to a valid time by adding an hour. See examples. If you want to ##' get NA for invalid date-times use [fit_to_timeline()] explicitly. ##' ##' @examples ##' ##' ## ** orders are much easier to write ** ##' x <- c("09-01-01", "09-01-02", "09-01-03") ##' parse_date_time(x, "ymd") ##' parse_date_time(x, "y m d") ##' parse_date_time(x, "%y%m%d") ##' # "2009-01-01 UTC" "2009-01-02 UTC" "2009-01-03 UTC" ##' ##' ## ** heterogenuous date-times ** ##' x <- c("09-01-01", "090102", "09-01 03", "09-01-03 12:02") ##' parse_date_time(x, c("ymd", "ymd HM")) ##' ##' ## ** different ymd orders ** ##' x <- c("2009-01-01", "02022010", "02-02-2010") ##' parse_date_time(x, c("dmY", "ymd")) ##' ## "2009-01-01 UTC" "2010-02-02 UTC" "2010-02-02 UTC" ##' ##' ## ** truncated time-dates ** ##' x <- c("2011-12-31 12:59:59", "2010-01-01 12:11", "2010-01-01 12", "2010-01-01") ##' parse_date_time(x, "Ymd HMS", truncated = 3) ##' ##' ## ** specifying exact formats and avoiding training and guessing ** ##' parse_date_time(x, c("%m-%d-%y", "%m%d%y", "%m-%d-%y %H:%M"), exact = TRUE) ##' parse_date_time(c('12/17/1996 04:00:00','4/18/1950 0130'), ##' c('%m/%d/%Y %I:%M:%S','%m/%d/%Y %H%M'), exact = TRUE) ##' ##' ## ** quarters and partial dates ** ##' parse_date_time(c("2016.2", "2016-04"), orders = "Yq") ##' parse_date_time(c("2016", "2016-04"), orders = c("Y", "Ym")) ##' ##' ## ** fast parsing ** ##' \dontrun{ ##' options(digits.secs = 3) ##' ## random times between 1400 and 3000 ##' tt <- as.character(.POSIXct(runif(1000, -17987443200, 32503680000))) ##' tt <- rep.int(tt, 1000) ##' ##' system.time(out <- as.POSIXct(tt, tz = "UTC")) ##' system.time(out1 <- ymd_hms(tt)) # constant overhead on long vectors ##' system.time(out2 <- parse_date_time2(tt, "YmdHMOS")) ##' system.time(out3 <- fast_strptime(tt, "%Y-%m-%d %H:%M:%OS")) ##' ##' all.equal(out, out1) ##' all.equal(out, out2) ##' all.equal(out, out3) ##' } ##' ##' ## ** how to use `select_formats` argument ** ##' ## By default %Y has precedence: ##' parse_date_time(c("27-09-13", "27-09-2013"), "dmy") ##' ##' ## to give priority to %y format, define your own select_format function: ##' ##' my_select <- function(trained, drop=FALSE, ...){ ##' n_fmts <- nchar(gsub("[^%]", "", names(trained))) + grepl("%y", names(trained))*1.5 ##' names(trained[ which.max(n_fmts) ]) ##' } ##' ##' parse_date_time(c("27-09-13", "27-09-2013"), "dmy", select_formats = my_select) ##' ##' ## ** invalid times with "fast" parsing ** ##' parse_date_time("2010-03-14 02:05:06", "YmdHMS", tz = "America/New_York") ##' parse_date_time2("2010-03-14 02:05:06", "YmdHMS", tz = "America/New_York") ##' parse_date_time2("2010-03-14 02:05:06", "YmdHMS", tz = "America/New_York", lt = TRUE) parse_date_time <- function(x, orders, tz = "UTC", truncated = 0, quiet = FALSE, locale = Sys.getlocale("LC_TIME"), select_formats = .select_formats, exact = FALSE, train = TRUE, drop = FALSE) { ## backward compatible hack if (is.null(tz)) tz <- "" orig_locale <- Sys.getlocale("LC_TIME") Sys.setlocale("LC_TIME", locale) on.exit(Sys.setlocale("LC_TIME", orig_locale)) x <- as.character(.num_to_date(x)) if (truncated != 0) orders <- .add_truncated(orders, truncated) .local_parse <- function(x, first = FALSE) { formats <- if (exact) { orders } else { train <- .get_train_set(x) .best_formats(train, orders, locale = locale, select_formats, drop = drop) } if (length(formats) > 0) { out <- .parse_date_time(x, formats, tz = tz, quiet = quiet, locale = locale) new_na <- is.na(out) if (any(new_na)) { x <- x[new_na] if (length(x) == length(out)) { # don't recur if failed for all failed <<- length(x) } else { out[new_na] <- .local_parse(x) } } out } else { if (first && !quiet) { warning("All formats failed to parse. No formats found.", call. = FALSE) warned <<- TRUE } failed <<- length(x) NA } } failed <- 0L warned <- FALSE to_parse <- which(!is.na(x) & nzchar(x)) ## missing data might be "" ## prepare an NA vector out <- .POSIXct(rep.int(NA_real_, length(x)), tz = tz) if (length(to_parse)) { out[to_parse] <- .local_parse(x[to_parse], TRUE) if (failed > 0 && !quiet && !warned) warning(" ", failed, " failed to parse.", call. = FALSE) } out } parse_dt <- function(x, orders, is_format = FALSE, return_lt = FALSE, cutoff_2000 = 68L) { .Call(C_parse_dt, x, orders, as.logical(is_format), as.logical(return_lt), as.integer(cutoff_2000)) } ##' @description ##' `parse_date_time2()` is a fast C parser of numeric ##' orders. ##' ##' @rdname parse_date_time ##' @export ##' @param lt logical. If TRUE returned object is of class POSIXlt, and POSIXct ##' otherwise. For compatibility with base `strptime` function default is TRUE ##' for `fast_strptime` and FALSE for `parse_date_time2`. ##' @param cutoff_2000 integer. For `y` format, two-digit numbers smaller or equal to ##' `cutoff_2000` are parsed as 20th's century, 19th's otherwise. Available only ##' for functions relying on `lubridate`s internal parser. parse_date_time2 <- function(x, orders, tz = "UTC", exact = FALSE, lt = FALSE, cutoff_2000 = 68L){ if (length(orders) > 1) warning("Multiple orders supplied. Only first order is used.") if (!exact) orders <- gsub("[^[:alpha:]]+", "", as.character(orders[[1]])) ## remove all separators if (lt) { .mklt(parse_dt(x, orders, FALSE, TRUE, cutoff_2000), tz) } else { if (tz == "UTC"){ .POSIXct(parse_dt(x, orders, FALSE, FALSE, cutoff_2000), tz = "UTC") } else { as.POSIXct(.mklt(parse_dt(x, orders, FALSE, TRUE, cutoff_2000), tz)) } } } ##' @description ##' `fast_strptime()` is a fast C parser of numeric formats only ##' that accepts explicit format arguments, just as ##' [base::strptime()]. ##' @rdname parse_date_time ##' @export ##' @param format a character string of formats. It should include all the ##' separators and each format must be prefixed with %, just as in the format ##' argument of `strptime()`. fast_strptime <- function(x, format, tz = "UTC", lt = TRUE, cutoff_2000 = 68L) { if (length(format) > 1) warning("Multiple formats supplied. Only first format is used.") format <- as.character(format[[1]]) if (lt) { .mklt(parse_dt(x, format, TRUE, TRUE, cutoff_2000), tz) } else{ if (tz == "UTC") { .POSIXct(parse_dt(x, format, TRUE, FALSE, cutoff_2000), "UTC") } else { as.POSIXct(.mklt(parse_dt(x, format, TRUE, TRUE, cutoff_2000), tz)) } } } ### INTERNAL .mklt <- function(dtlist, tz){ na_fill <- rep_len(NA_integer_, length(dtlist$sec)) dtlist[["wday"]] <- na_fill dtlist[["yday"]] <- na_fill dtlist[["isdst"]] <- -1L .POSIXlt(dtlist, tz = tz) } .parse_date_time <- function(x, formats, tz, quiet, locale){ ## print(formats) # for debugging out <- .strptime(x, formats[[1]], tz = tz, quiet = quiet, locale = locale) na <- is.na(out) newx <- x[na] verbose <- getOption("lubridate.verbose") if (!is.null(verbose) && verbose) message(" ", sum(!na), " parsed with ", gsub("^@|@$", "", formats[[1]])) ## recursive parsing if (length(formats) > 1 && length(newx) > 0) out[na] <- .parse_date_time(newx, formats[-1], tz = tz, quiet = quiet, locale = locale) ## return POSIXlt out } .strptime <- function(x, fmt, tz = "UTC", quiet = FALSE, locale = NULL){ ## Depending on fmt we might need to preprocess x. ## ISO8601 and internal parser are the only cases so far. ## %Ou: "2013-04-16T04:59:59Z" ## %Oo: "2013-04-16T04:59:59+01" ## %Oz: "2013-04-16T04:59:59+0100" ## %OO: "2013-04-16T04:59:59+01:00" ## is_posix <- 0 < regexpr("^[^%]*%Y[^%]+%m[^%]+%d[^%]+(%H[^%](%M[^%](%S)?)?)?[^%Z]*$", fmt) c_parser <- 0 < regexpr("^[^%0-9]*(%([YymdqIHMSz]|O[SzuoOpmb])[^%0-9Z]*)+$", fmt) zpos <- regexpr("%O((?z)|(?u)|(?o)|(?O))", fmt, perl = TRUE) if (c_parser) { ## C PARSER: out <- fast_strptime(x, fmt, tz = "UTC", lt = FALSE) if (tz != "UTC") { out <- if (zpos > 0){ if (!quiet) message("Date in ISO8601 format; converting timezone from UTC to \"", tz, "\".") with_tz(out, tzone = tz) } else { ## force_tz is very slow force_tz(out, tzone = tz) } } out } else { ## STRPTIME PARSER: ## strptime doesn't accept 'locale' argument; need a hard reset if (!is.null(locale)) { old_lc_time <- Sys.getlocale("LC_TIME") if (old_lc_time != locale){ Sys.setlocale("LC_TIME", locale) on.exit(Sys.setlocale("LC_TIME", old_lc_time)) } } if (zpos > 0){ ## If ISO8601 -> pre-process x and fmt capt <- attr(zpos, "capture.names")[attr(zpos, "capture.start") > 0][[2]] ## <- second subexp repl <- switch(capt, z = "%z", u ="Z", ## substitute +aa with +aa00 o = { x <- sub("([+-]\\d{2}(?=\\D+)?$)", "\\100", x, perl = TRUE) "%z"}, ## substitute +aa:bb with +aabb O = { x <- sub("([+-]\\d{2}):(?=[^:]+$)", "\\1", x, perl = TRUE) "%z"}, stop("Unrecognised capture detected; please report this bug")) str_sub(fmt, zpos, zpos + attr(zpos, "match.length") - 1) <- repl ## user has supplied tz argument -> convert to tz if (tz != "UTC"){ if (!quiet) message("Date in ISO8601 format; converting timezone from UTC to \"", tz, "\".") return(with_tz(strptime(.enclose(x), .enclose(fmt), "UTC"), tzone = tz)) } } strptime(.enclose(x), .enclose(fmt), tz) } } ## Expand format strings to also include truncated formats ## Get locations of letters as vector ## Choose the number at the n - truncated place in the vector ## return the substring created by 1 to tat number. .add_truncated <- function(orders, truncated){ out <- orders if (truncated > 0) { trunc_one <- function(order) { alphas <- gregexpr("[a-zA-Z]", order)[[1]] start <- max(0, length(alphas) - truncated) cut_points <- alphas[start:(length(alphas)-1)] truncs <- c() for (j in seq_along(cut_points)) truncs <- c(truncs, substr(order, 1, cut_points[j])) truncs } } else { trunc_one <- function(order) { alphas <- gregexpr("[a-zA-Z]", order)[[1]][-1] end <- max(1, abs(truncated) - 1) cut_points <- alphas[1:end] truncs <- c() for (j in seq_along(cut_points)) truncs <- c(truncs, substr(order, cut_points[j], nchar(order))) truncs } } for (i in seq_along(orders)) { out <- c(out, trunc_one(orders[i])) } out } .xxx_hms_truncations <- list(T = c("R", "r", ""), R = c("r", ""), r = "") .parse_xxx_hms <- function(..., orders, truncated, quiet, tz, locale){ ## !!! NOTE: truncated operates on first element in ORDERS ! if (truncated > 0){ ## Take first 3 formats and append formats from .xxx_hms_truncations ## co responding to the 4th format letter in order[[1]] -- T, R or r. xxx <- substr(orders[[1]], 1, 3) ## add <- paste(xxx, .xxx_hms_truncations[[substr(orders[[1]], 4, 4)]], sep = "") rest <- length(add) - truncated if (rest < 0) orders <- c(orders, add, .add_truncated(xxx, abs(rest))) else orders <- c(orders, add[1:truncated]) } dates <- unlist(lapply(list(...), .num_to_date), use.names = FALSE) parse_date_time(dates, orders, tz = tz, quiet = quiet, locale = locale) } .parse_xxx <- function(..., orders, quiet, tz, locale, truncated){ dates <- unlist(lapply(list(...), .num_to_date), use.names = FALSE) if (is.null(tz)) { as.Date.POSIXct(parse_date_time(dates, orders, quiet = quiet, tz = "UTC", locale = locale, truncated = truncated)) } else { parse_date_time(dates, orders, quiet = quiet, tz = tz, locale = locale, truncated = truncated) } } .num_to_date <- function(x) { if (is.numeric(x)) { out <- rep.int(as.character(NA), length(x)) nnas <- !is.na(x) x <- format(x[nnas], scientific = FALSE, trim = TRUE) x <- paste(ifelse(nchar(x) %% 2 == 1, "0", ""), x, sep = "") out[nnas] <- x out }else as.character(x) } .parse_iso_dt <- function(x, tz) { parse_date_time(x, orders = c("ymdTz", "ymdT", "ymd"), tz = tz, train = FALSE) } as_POSIXct <- function(x, tz) { if (is.character(x)) .parse_iso_dt(x, tz = tz) else if (!is.POSIXct(x)) as.POSIXct(x, tz = tz) else x } ## parse.r ends here lubridate/R/accessors-year.r0000644000176200001440000000307113201152061015524 0ustar liggesusers#' @include periods.r NULL #' Get/set years component of a date-time #' #' Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, #' zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts #' objects. #' #' year does not yet support years before 0 C.E. #' #' @param x a date-time object #' @param value a numeric object #' @return the years element of x as a decimal number #' @keywords utilities manip chron methods #' @references #' \url{http://en.wikipedia.org/wiki/ISO_week_date} #' \url{http://www.cmmcp.org/epiweek.htm} #' @examples #' x <- ymd("2012-03-26") #' year(x) #' year(x) <- 2001 #' year(x) > 1995 #' @export year <- function(x) UseMethod("year") #' @export year.default <- function(x) as.POSIXlt(x, tz = tz(x))$year + 1900 #' @export year.Period <- function(x) slot(x, "year") #' @rdname year #' @export "year<-" <- function(x, value) { x <- x + years(value - year(x)) } setGeneric("year<-") #' @export setMethod("year<-", signature("Period"), function(x, value) { slot(x, "year") <- value x }) .other_year <- function(x, week_start = 1) { x <- as.POSIXlt(x) date <- make_date(year(x), month(x), day(x)) isodate <- date + ddays(4 - wday(date, week_start = week_start)) year(isodate) } #' @rdname year #' @description #' `isoyear()` returns years according to the ISO 8601 week calendar. #' @export isoyear <- function(x) { .other_year(x, 1) } #' @rdname year #' @description #' `epiyear()` returns years according to the epidemilogical week calendars. #' @export epiyear <- function(x) { .other_year(x, 7) } lubridate/R/data.r0000644000176200001440000000117613201152061013516 0ustar liggesusers#' Lakers 2008-2009 basketball data set #' #' This data set contains play by play statistics of each Los #' Angeles Lakers basketball game in the 2008-2009 season. Data #' includes the date, opponent, and type of each game (home or #' away). Each play is described by the time on the game clock #' when the play was made, the period in which the play was #' attempted, the type of play, the player and team who made the #' play, the result of the play, and the location on the court #' where each play was made. #' #' @name lakers #' @docType data #' @references Originally taken from www.basketballgeek.com/data/. #' @keywords data NULL lubridate/R/ops-compare.r0000644000176200001440000000262213236361663015051 0ustar liggesusers##' @include util.r NULL ## #' @export ## setMethod("<", signature(e1 = "POSIXct", e2 = "Date"), ## function(e1, e2) { ## cat("here") ## callNextMethod(e1, .POSIXct(e2, tz = attr(e1, "tzone"))) ## }) ## #' @export ## setMethod("<", signature(e1 = "Date", e2 = "POSIXct"), ## function(e1, e2) { ## cat("here") ## callNextMethod(.POSIXct(e1, tz = attr(e2, "tzone")), e2) ## }) comp_posix_date <- function(e1, e2) { if (nargs() == 1) stop(gettextf("unary '%s' not defined for \"%s\" objects", .Generic, class(e1)), domain = NA) if (inherits(e1, "POSIXlt")) e1 <- as.POSIXct(e1) if (inherits(e2, "POSIXlt")) e2 <- as.POSIXct(e2) if (is.character(e1)) { e1 <- if (is.Date(e2)) as.Date(e1) else as.POSIXct(e1) } if (is.character(e2)) { e2 <- if (is.Date(e1)) as.Date(e2) else as.POSIXct(e2) } if (is.POSIXct(e1) && is.Date(e2)) { e2 <- date_to_posix(e2, tz(e1)) base::check_tzones(e1, e2) } else if (is.Date(e1) && is.POSIXct(e2)) { e1 <- date_to_posix(e1, tz = tz(e2)) base::check_tzones(e1, e2) } NextMethod(.Generic) } ## Nothing else seems to work, only this sneaky trick. evalqOnLoad({ for (op in c("<", ">", "==", ">=", "<=", "!=")) { registerS3method(op, "Date", comp_posix_date) registerS3method(op, "POSIXt", comp_posix_date) } }) lubridate/R/deprecated.r0000644000176200001440000001342013201152061014700 0ustar liggesusers##' Deprecated functions in the lubridate package ##' @param x numeric value to be converted into duration ##' @param ... arguments to be passed to the functions ##' (obscured to enforce the usage of new functions) ##' @rdname Deprecated ##' @keywords internal ##' @name Deprecated-lubridate NULL ## modified ggplot2:::gg_dep .deprecated_fun <- function(replacement, version, n_call = 1) { name <- as.character(sys.call(-(n_call))[[1]]) name <- sprintf("'%s'", name[[length(name)]]) replacement <- sprintf("; use '%s' instead", replacement) .deprecated(name, replacement, version) } .deprecated_arg <- function(arg, version, n_call = 1) { name <- as.character(sys.call(-n_call)[[1]]) mes <- sprintf("Argument '%s' of '%s'", arg, name) .deprecated(mes, "", version) } .deprecated <- function(name, replacement = NULL, version) { v <- as.package_version(version) cv <- packageVersion("lubridate") replacement <- if (is.null(replacement)) "" else replacement ## If current major number is greater than last-good major number, or if ## current minor number is more than 2 greater than last-good minor number, ## give error. if (cv[[1, 1]] > v[[1, 1]] || cv[[1, 2]] > v[[1, 2]] + 2) { stop(sprintf("%s is defunct%s. Deprecated in version '%s'.", name, replacement, version), call. = FALSE) } else if (cv[[1, 2]] > v[[1, 2]]) { ## If minor number differs by one, give warning warning(sprintf("%s is deprecated%s. Deprecated in version '%s'.", name, replacement, version), call. = FALSE) } else if (cv[[1, 3]] >= v[[1, 3]]) { ## If only subminor number is greater, give message message(sprintf("%s is deprecated%s. Deprecated in version '%s'.", name, replacement, version)) } invisible() } ##' @rdname Deprecated ##' @export new_period <- function(...) { .deprecated_fun("period", "1.5.0") period(...) } ##' @rdname Deprecated ##' @export new_interval <- function(...) { .deprecated_fun("interval", "1.5.0") interval(...) } ##' @rdname Deprecated ##' @export new_duration <- function(...) { .deprecated_fun("duration", "1.5.0") duration(...) } ##' @rdname Deprecated ##' @export new_difftime <- function(...) { .deprecated_fun("make_difftime", "1.5.0") make_difftime(...) } #' @export #' @rdname Deprecated eseconds <- function(x = 1) { .deprecated_fun("dseconds", "1.5.0") new("Duration", x) } #' @export #' @rdname Deprecated eminutes <- function(x = 1) { .deprecated_fun("dminutes", "1.5.0") new("Duration", x * 60) } #' @export #' @rdname Deprecated ehours <- function(x = 1) { .deprecated_fun("dhours", "1.5.0") new("Duration", x * 3600) } #' @export #' @rdname Deprecated edays <- function(x = 1) { .deprecated_fun("ddays", "1.5.0") new("Duration", x * 86400) } #' @export #' @rdname Deprecated eweeks <- function(x = 1) { .deprecated_fun("dweeks", "1.5.0") new("Duration", x * 604800) } #' @export #' @rdname Deprecated eyears <- function(x = 1) { .deprecated_fun("dyears", "1.5.0") new("Duration", x * 60 * 60 * 24 * 365) } #' @export #' @rdname Deprecated emilliseconds <- function(x = 1) { .deprecated_fun("dmilliseconds", "1.5.0") new("Duration", x / 1000) } #' @export #' @rdname Deprecated emicroseconds <- function(x = 1) { .deprecated_fun("dmicroseconds", "1.5.0") new("Duration", x / 1000 / 1000) } #' @export #' @rdname Deprecated enanoseconds <- function(x = 1) { .deprecated_fun("dnanoseconds", "1.5.0") new("Duration", x / 1000 / 1000 / 1000) } #' @export #' @rdname Deprecated epicoseconds <- function(x = 1) { .deprecated_fun("dpicoseconds", "1.5.0") new("Duration", x / 1000 / 1000 / 1000 / 1000) } #' @export #' @rdname Deprecated here <- function() { .deprecated_fun("now", "1.5.6") now() } #' @export #' @param order_by Return names alphabetically (the default) or from West to #' East. #' @rdname Deprecated olson_time_zones <- function(order_by = c("name", "longitude")) { .deprecated_fun("OlsonNames", "1.5.6") order_by <- match.arg(order_by) ## compile possible locations for zoneinfo/zone.tab tzdirs <- c( R.home("share"), # Windows ## taken from OlsonNames in R3.0.3 "/usr/share", "/usr/share/lib", "/usr/lib/zoneinfo", "/usr/local/etc", "/etc", "/usr/etc") tzfiles <- c(file.path(tzdirs, "zoneinfo", "zone.tab"), ## special treatment of Soloaris > 9 (versions < 8 seem not to ## have it at all) "/usr/share/lib/zoneinfo/tab/zone_sun.tab") tzfiles <- tzfiles[file.exists(tzfiles)] if (length(tzfiles) == 0) { warning("zone.tab file not found in any candidate locations: ", paste(tzdirs, collapse = " ")) } tzfile <- tzfiles[[1]] tzones <- read.delim( tzfile, row.names = NULL, header = FALSE, col.names = c("country", "coords", "name", "comments"), as.is = TRUE, fill = TRUE, comment.char = "#" ) o <- order(switch( order_by, name = tzones$name, longitude = { longitude_string <- sub("^[+-][[:digit:]]+", "", tzones$coords) nch <- nchar(longitude_string) sign <- ifelse( substring(longitude_string, 1, 1) == "+", 1, -1 ) nss <- function(first, last) { as.numeric(substring(longitude_string, first, last)) } sign * ifelse( nch == 5, 3600 * nss(2, 3) + 60 * nss(4, 5), ifelse( nch == 6, 3600 * nss(2, 4) + 60 * nss(6, 6), ifelse( nch == 7, 3600 * nss(2, 3) + 60 * nss(4, 5) + nss(6, 7), 3600 * nss(2, 4) + 60 * nss(6, 6) + nss(7, 8) ) ) ) } )) tzones$name[o] } lubridate/R/pretty.r0000644000176200001440000000617513234633351014154 0ustar liggesusers#' Computes attractive axis breaks for date-time data #' #' pretty.dates indentifies which unit of time the sub-intervals should be #' measured in to provide approximately n breaks. It then chooses a "pretty" #' length for the sub-intervals and sets start and endpoints that 1) span the #' entire range of the data, and 2) allow the breaks to occur on important #' date-times (i.e. on the hour, on the first of the month, etc.) #' #' @param x a vector of POSIXct, POSIXlt, Date, or chron date-time objects #' @param n integer value of the desired number of breaks #' @param ... additional arguments to pass to function #' @return a vector of date-times that can be used as axis tick marks or bin breaks #' @keywords dplot utilities chron #' @export #' @examples #' x <- seq.Date(as.Date("2009-08-02"), by = "year", length.out = 2) #' pretty_dates(x, 12) pretty_dates <- function(x, n, ...) { otz <- Sys.getenv("TZ") if (Sys.getenv("TZ") == "") otz <- "unset" Sys.setenv(TZ = tz(x[1])) on.exit(if (otz == "unset") Sys.unsetenv("TZ") else Sys.setenv(TZ = otz)) rng <- range(x) diff <- difftime(rng[2], rng[1], units = "secs") binunits <- pretty_unit(diff/n) f <- get(paste("pretty", binunits, sep = "_"), mode = "function") binlength <- f(diff, n) start <- pretty_point(min(rng), binunits, binlength) end <- pretty_point(max(rng), binunits, binlength, start = FALSE) breaks <- seq.POSIXt(start, end, paste(binlength, binunits)) breaks } pretty_unit <- function(x, ...) { if (x > 3600*24*365) return("year") if (x > 3600*24*30) return("month") if (x > 3600*24) return("day") if (x > 3600) return("hour") if (x > 60) return("min") else return("sec") } pretty_sec <- function(x, n, ...) { lengths <- c(1, 2, 5, 10, 15, 30, 60) fit <- abs(x - lengths*n) lengths[which.min(fit)] } pretty_min <- function(x, n, ...) { span <- x/60 lengths <- c(1, 2, 5, 10, 15, 30, 60) fit <- abs(span - lengths*n) lengths[which.min(fit)] } pretty_hour <- function(x, n, ...) { span <- x / 3600 lengths <- c(1, 2, 3, 4, 6, 8, 12, 24) fit <- abs(span - lengths*n) lengths[which.min(fit)] } pretty_day <- function(x, n, ...) { span <- x / (3600 * 24) pretty(1:span, n = n)[2] } pretty_month <- function(x, n, ...) { span <- x / (3600 * 24 * 30) lengths <- c(1, 2, 3, 4, 6, 12) fit <- abs(span - lengths*n) lengths[which.min(fit)] } pretty_year <- function(x, n, ...) { span <- x / (3600 * 24 * 365) pretty(1:span, n = n)[2] } pretty_point <- function(x, units, length, start = TRUE, ...) { x <- as.POSIXct(x) if (units %in% c("day", "year")) { if (start) return(floor_date(x, units)) else return(ceiling_date(x, units)) } else { floors <- c("sec", "min", "hour", "day", "month", "year") floorto <- floors[match(units, floors) + 1L] lower <- floor_date(x, floorto) upper <- ceiling_date(x, floorto) points <- seq.POSIXt(lower, upper, paste(length, units)) if (start) points <- points[points <= x] else points <- points[points >= x] fit <- as.duration(x - points) fit <- abs(as.double(fit, "secs")) points[which.min(fit)] } } lubridate/R/ops-division.r0000644000176200001440000001360313201152061015226 0ustar liggesusers#' @include timespans.r #' @include durations.r #' @include intervals.r #' @include periods.r #' @include difftimes.r #' @include numeric.r NULL divide_duration_by_duration <- function(dur1, dur2) dur1@.Data / dur2@.Data divide_duration_by_difftime <- function(dur, diff) dur@.Data / as.numeric(diff, units = "secs") divide_duration_by_number <- function(dur, num) new("Duration", dur@.Data / num) divide_interval_by_duration <- function(int, dur) { int@.Data / dur@.Data } adjust_estimate <- function(est, int, per) { start <- int_start(int) end <- int_end(int) est <- ceiling(est) up_date <- add_with_rollback(start, est * per) while (length(which <- which(up_date < end))) { up_date[which] <- add_with_rollback(up_date[which], per[which]) est[which] <- est[which] + 1 } low_date <- up_date ## add_with_rollback(up_date, -per) while (length(which <- which(low_date > end))) { up_date[which] <- low_date[which] low_date[which] <- add_with_rollback(low_date[which], -per[which]) est[which] <- est[which] - 1 } frac <- as.numeric(difftime(end, low_date, units = "secs"))/ as.numeric(difftime(up_date, low_date, units = "secs")) frac[low_date == up_date] <- 0 est + frac } divide_interval_by_period <- function(int, per) { if (length(int) == 0 || length(per) == 0) return(numeric()) estimate <- int/as.duration(per) not_nas <- !is.na(estimate) timespans <- match_lengths(int, per) if (all(not_nas)) { adjust_estimate(estimate, timespans[[1]], timespans[[2]]) } else { int2 <- timespans[[1]][not_nas] per2 <- timespans[[2]][not_nas] estimate[not_nas] <- adjust_estimate(estimate[not_nas], int2, per2) estimate } } divide_interval_by_difftime <- function(int, diff) { int@.Data / as.double(diff, units = "secs") } divide_interval_by_number <- function(int, num) { starts <- int@start + rep(0, length(num)) new("Interval", int@.Data / num, start = starts, tzone = int@tzone) } divisible_period <- function(per, anchor) { per@month <- per@month + 12*per@year per@year <- rep(0, length(per@year)) secs.in.months <- as.numeric(anchor + months(per@month)) - as.numeric(anchor) days.in.months <- round(secs.in.months/86400) per@day <- per@day + days.in.months per@month <- 0 per } divide_period_by_period <- function(per1, per2) { message("estimate only: convert to intervals for accuracy") period_to_seconds(per1) / period_to_seconds(per2) } divide_period_by_number <- function(per, num) { new("Period", per@.Data / num, year = per@year / num, month = per@month / num, day = per@day / num, hour = per@hour / num, minute = per@minute / num) } divide_difftime_by_duration <- function(dif, dur) as.numeric(dif, units = "secs") / dur@.Data #' @export setMethod("/", signature(e1 = "Duration", e2 = "Duration"), function(e1, e2) divide_duration_by_duration(e1, e2)) #' @export setMethod("/", signature(e1 = "Duration", e2 = "Interval"), function(e1, e2) { stop("Incompatible timespan classes:\n change class with as.duration() or put interval in numerator.") }) #' @export setMethod("/", signature(e1 = "Duration", e2 = "Period"), function(e1, e2) { stop("Incompatible timespan classes:\n change class with as.duration() or as.period()") }) #' @export setMethod("/", signature(e1 = "Duration", e2 = "difftime"), function(e1, e2) divide_duration_by_difftime(e1, e2)) #' @export setMethod("/", signature(e1 = "Duration", e2 = "numeric"), function(e1, e2) divide_duration_by_number(e1, e2)) #' @export setMethod("/", signature(e1 = "Interval", e2 = "Duration"), function(e1, e2) divide_interval_by_duration(e1, e2)) #' @export setMethod("/", signature(e1 = "Interval", e2 = "Interval"), function(e1, e2) { stop("interval / interval not defined") }) #' @export setMethod("/", signature(e1 = "Interval", e2 = "Period"), function(e1, e2) divide_interval_by_period(e1, e2)) #' @export setMethod("/", signature(e1 = "Interval", e2 = "difftime"), function(e1, e2) divide_interval_by_difftime(e1, e2)) #' @export setMethod("/", signature(e1 = "Interval", e2 = "numeric"), function(e1, e2) divide_interval_by_number(e1, e2)) #' @export setMethod("/", signature(e1 = "Period", e2 = "Duration"), function(e1, e2) { stop("Incompatible timespan classes:\n change class with as.duration() or as.period()") }) #' @export setMethod("/", signature(e1 = "Period", e2 = "Interval"), function(e1, e2) { stop("Incompatible timespan classes:\n change class with as.period() or put interval in numerator.") }) #' @export setMethod("/", signature(e1 = "Period", e2 = "Period"), function(e1, e2) divide_period_by_period(e1, e2)) #' @export setMethod("/", signature(e1 = "Period", e2 = "difftime"), function(e1, e2) { stop("Incompatible timespan classes:\n change class with as.duration() or as.period()") }) #' @export setMethod("/", signature(e1 = "Period", e2 = "numeric"), function(e1, e2) divide_period_by_number(e1, e2)) #' @export setMethod("/", signature(e1 = "difftime", e2 = "Duration"), function(e1, e2) divide_difftime_by_duration(e1, e2)) #' @export setMethod("/", signature(e1 = "difftime", e2 = "Interval"), function(e1, e2) { stop("Incompatible timespan classes:\n change class with as.duration() or put interval in numerator.") }) #' @export setMethod("/", signature(e1 = "difftime", e2 = "Period"), function(e1, e2) { stop("Incompatible timespan classes:\n change class with as.duration() or as.period()") }) #' @export setMethod("/", signature(e1 = "numeric", e2 = "Duration"), function(e1, e2) stop("Cannot divide numeric by duration")) #' @export setMethod("/", signature(e1 = "numeric", e2 = "Interval"), function(e1, e2) stop("Cannot divide numeric by interval")) #' @export setMethod("/", signature(e1 = "numeric", e2 = "Period"), function(e1, e2) stop("Cannot divide numeric by period")) lubridate/R/zzz.R0000644000176200001440000000174613201152061013405 0ustar liggesusers .onLoad <- function(libname, pkgname) { ## CCTZ needs zoneinfo. On windows we set it to R's own zoneinfo. On unix like ## it's in "/usr/share/zoneinfo" where CCTZ looks by default. On some systems ## (solaris, osx) it might be in a different location. So, help ourselves by ## setting the TZDIR env var, but only if it's not already set. if (Sys.getenv("TZDIR") == "") { ## adapted from OlsonNames function tzdir <- if (.Platform$OS.type == "windows") { file.path(R.home("share"), "zoneinfo") } else if (!file.exists("/usr/share/zoneinfo")) { tzdirs <- c(file.path(R.home("share"), "zoneinfo"), "/usr/share/lib/zoneinfo", "/usr/lib/zoneinfo", "/usr/local/etc/zoneinfo", "/etc/zoneinfo", "/usr/etc/zoneinfo") tzdirs <- tzdirs[file.exists(tzdirs)] if (length(tzdirs)) tzdirs[[1]] else NULL } if (!is.null(tzdir)) { Sys.setenv(TZDIR = tzdir) } } } lubridate/R/intervals.r0000644000176200001440000005436313263134500014630 0ustar liggesusers#' @include timespans.r #' @include parse.r #' @include util.r NULL check_interval <- function(object) { errors <- character() if (!is.numeric(object@.Data)) { msg <- "Span length must be numeric." errors <- c(errors, msg) } if (!is(object@start, "POSIXct")) { msg <- "Start date must be in POSIXct format." errors <- c(errors, msg) } if (length(object@.Data) != length(object@start)) { msg <- paste("Inconsistent lengths: spans = ", length(object@.Data), ", start dates = ", length(object@start), sep = "") errors <- c(errors, msg) } if (length(errors) == 0) TRUE else errors } .units_within_seconds <- function(secs, unit = "second") { ## return a list suitable to pass to new("Period", ...) switch(unit, second = list(secs), minute = list(secs %% 60, minute = secs %/% 60), hour = c(.units_within_seconds(secs %% 3600, "minute"), list(hour = secs %/% 3600)), day = c(.units_within_seconds(secs %% 86400, "hour"), list(day = secs %/% 86400)), stop("Unsuported unit ", unit)) } #' Interval class #' #' Interval is an S4 class that extends the [Timespan-class] class. An #' Interval object records one or more spans of time. Intervals record these #' timespans as a sequence of seconds that begin at a specified date. Since #' intervals are anchored to a precise moment of time, they can accurately be #' converted to [Period-class] or [Duration-class] class objects. This #' is because we can observe the length in seconds of each period that begins on a #' specific date. Contrast this to a generalized period, which may not have a #' consistent length in seconds (e.g. the number of seconds in a year will change #' if it is a leap year). #' #' Intervals can be both negative and positive. Negative intervals progress #' backwards from the start date; positive intervals progress forwards. #' #' Interval class objects have two slots: .Data, a numeric object equal to the number #' of seconds in the interval; and start, a POSIXct object that specifies the time #' when the interval starts. #' #' @aliases intervals #' @export setClass("Interval", contains = c("Timespan", "numeric"), slots = c(start = "POSIXct", tzone = "character"), validity = check_interval) #' @export setMethod("show", signature(object = "Interval"), function(object) { print(format.Interval(object), quote = F) }) #' @export format.Interval <- function(x, ...) { if (length(x@.Data) == 0) return("Interval(0)") paste(format(x@start, tz = x@tzone, usetz = TRUE), "--", format(x@start + x@.Data, tz = x@tzone, usetz = TRUE), sep = "") } #' @export setMethod("c", signature(x = "Interval"), function(x, ...) { elements <- lapply(list(...), as.interval) spans <- c(x@.Data, unlist(elements@.Data)) starts <- c(x@start, lapply(elements, int_start)) new("Interval", spans, start = starts, tzone = x@tzone) }) #' @export setMethod("rep", signature(x = "Interval"), function(x, ...) { new("Interval", rep(x@.Data, ...), start = rep(x@start, ...), tzone = x@tzone) }) #' @export setMethod("[", signature(x = "Interval"), function(x, i, j, ..., drop = TRUE) { new("Interval", x@.Data[i], start = x@start[i], tzone = x@tzone) } ) #' @export setMethod("[[", signature(x = "Interval"), function(x, i, j, ..., exact = TRUE) { new("Interval", x@.Data[i], start = x@start[i], tzone = x@tzone) } ) #' @export setMethod("[<-", signature(x = "Interval"), function(x, i, j, ..., value) { if (is.interval(value)) { x@.Data[i] <- value@.Data x@start[i] <- value@start new("Interval", x@.Data, start = x@start, tzone = x@tzone) } else { x@.Data[i] <- value new("Interval", x@.Data, start = x@start, tzone = x@tzone) } }) #' @export setMethod("[[<-", signature(x = "Interval"), function(x, i, j, ..., value) { if (is.interval(value)) { x@.Data[i] <- value@.Data x@start[i] <- value@start new("Interval", x@.Data, start = x@start, tzone = x@tzone) } else { x@.Data[i] <- value new("Interval", x@.Data, start = x@start, tzone = x@tzone) } }) #' @export setMethod("$", signature(x = "Interval"), function(x, name) { if (name == "span") name <- ".Data" slot(x, name) }) #' @export setMethod("$<-", signature(x = "Interval"), function(x, name, value) { if (name == "span") name <- ".Data" slot(x, name) <- value x }) #' @export unique.Interval <- function(x, ...) { df <- unique.data.frame(data.frame(data = x@.Data, start = x@start), ...) new("Interval", df$data, start = df$start, tzone = x@tzone) } #' Utilities for creation and manipulation of `Interval` objects #' #' `interval()` creates an [Interval-class] object with the specified start and #' end dates. If the start date occurs before the end date, the interval will be #' positive. Otherwise, it will be negative. Character vectors in ISO 8601 #' format are suported from v1.7.2. #' #' Intervals are time spans bound by two real date-times. Intervals can be #' accurately converted to either period or duration objects using #' [as.period()], [as.duration()]. Since an interval is anchored to a fixed #' history of time, both the exact number of seconds that passed and the number #' of variable length time units that occurred during the interval can be #' calculated. #' #' @export #' @param start,end POSIXt, Date or a character vectors. When `start` is a #' character vector and end is `NULL`, ISO 8601 specification is assumed but #' with much more permisive lubridate style parsing both for dates and periods #' (see examples). #' @param tzone a recognized timezone to display the interval in #' @param x an R object #' @return `interval()` -- [Interval-class] object. #' @seealso [Interval-class], [as.interval()], \code{\link{\%within\%}} #' @examples #' interval(ymd(20090201), ymd(20090101)) #' #' date1 <- ymd_hms("2009-03-08 01:59:59") #' date2 <- ymd_hms("2000-02-29 12:00:00") #' interval(date2, date1) #' interval(date1, date2) #' span <- interval(ymd(20090101), ymd(20090201)) #' #' ### ISO Intervals #' #' interval("2007-03-01T13:00:00Z/2008-05-11T15:30:00Z") #' interval("2007-03-01T13:00:00Z/P1Y2M10DT2H30M") #' interval("P1Y2M10DT2H30M/2008-05-11T15:30:00Z") #' interval("2008-05-11/P2H30M") #' #' ### More permisive parsing (as long as there are no intermittent / characters) #' interval("2008 05 11/P2hours 30minutes") #' interval("08 05 11/P 2h 30m") #' #' is.interval(period(months= 1, days = 15)) # FALSE #' is.interval(interval(ymd(20090801), ymd(20090809))) # TRUE interval <- function(start, end = NULL, tzone = tz(start)) { if (is.null(tzone)) { tzone <- tz(end) if (is.null(tzone)) tzone <- "UTC" } if (is.character(start) && is.null(end)) { return(parse_interval(start, tzone)) } if (is.Date(start)) start <- date_to_posix(start) if (is.Date(end)) end <- date_to_posix(end) start <- as_POSIXct(start, tzone) end <- as_POSIXct(end, tzone) span <- as.numeric(end) - as.numeric(start) starts <- start + rep(0, length(span)) if (tzone != tz(starts)) starts <- with_tz(starts, tzone) new("Interval", span, start = starts, tzone = tzone) } parse_interval <- function(x, tz) { mat <- str_split_fixed(x, "/", 2) pstart <- grepl("^P", mat[, 1]) pend <- grepl("^P", mat[, 2]) if (any(pstart & pend)) { stop(sprintf("Interval specified with period endpoints (%s)", x[pstart & pend][[1]])) } start <- .POSIXct(rep.int(NA_real_, length(x)), tz = tz) end <- .POSIXct(rep.int(NA_real_, length(x)), tz = tz) start[!pstart] <- .parse_iso_dt(mat[!pstart, 1], tz) end[!pend] <- .parse_iso_dt(mat[!pend, 2], tz = tz) end[pend] <- start[pend] + parse_period(mat[pend, 2]) start[pstart] <- end[pstart] - parse_period(mat[pstart, 1]) interval(start, end, tz) } #' #' \code{\%--\%} Creates an interval that covers the range spanned by two #' dates. It replaces the original behavior of \pkg{lubridate}, which created an #' interval by default whenever two date-times were subtracted. #' #' @export #' @rdname interval "%--%" <- function(start, end) interval(start, end) #' @rdname interval #' @export is.interval <- function(x) is(x, c("Interval")) #' #' #' `int_start()` and `int_start<-()` are accessors the start date of an #' interval. Note that changing the start date of an interval will change the #' length of the interval, since the end date will remain the same. #' #' @rdname interval #' @param int an interval object #' @return `int_start()` and `int_end()` return a POSIXct date object when #' used as an accessor. Nothing when used as a setter. #' @examples #' int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) #' int_start(int) #' int_start(int) <- ymd("2001-06-01") #' int #' #' int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) #' int_end(int) #' int_end(int) <- ymd("2002-06-01") #' int #' @export int_start <- function(int) int@start #' @rdname interval #' @param value interval's start/end to be assigned to `int` #' @export "int_start<-" <- function(int, value) { value <- as.POSIXct(value) span <- as.numeric(int@start + int@.Data - value, "secs") equal.lengths <- data.frame(span, value) int <- new("Interval", span, start = equal.lengths$value, tzone = int@tzone) } #' @description #' `int_end()` and `int_end<-()` are accessors the end date of an #' interval. Note that changing the end date of an interval will change the #' length of the interval, since the start date will remain the same. #' #' @rdname interval #' @export int_end <- function(int) int@start + int@.Data #' @rdname interval #' @export "int_end<-" <- function(int, value) { value <- as.POSIXct(value) span <- as.numeric(value - int@start, "secs") int <- new("Interval", span, start = int@start, tzone = int@tzone) } #' @rdname interval #' @return `int_length()` -- numeric length of the interval in #' seconds. A negative number connotes a negative interval. #' @examples #' int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) #' int_length(int) #' @export int_length <- function(int) int@.Data #' @description #' `int_flip()` reverses the order of the start date and end date in an #' interval. The new interval takes place during the same timespan as the #' original interval, but has the opposite direction. #' #' @rdname interval #' @return `int_flip()` -- flipped interval object #' @examples #' int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) #' int_flip(int) #' @export int_flip <- function(int) { new("Interval", -int@.Data, start = int@start + int@.Data, tzone = int@tzone) } #' @description #' `int_shift()` shifts the start and end dates of an interval up or down the #' timeline by a specified amount. Note that this may change the exact length of #' the interval if the interval is shifted by a Period object. Intervals shifted #' by a Duration or difftime object will retain their exact length in seconds. #' #' @rdname interval #' @param by A period or duration object to shift by (for `int_shift`) #' @return `int_shift()` -- an Interval object #' @examples #' int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) #' int_shift(int, duration(days = 11)) #' int_shift(int, duration(hours = -1)) #' @export int_shift <- function(int, by) { if (!is.timespan(by)) stop("by is not a recognized timespan object") if (is.interval(by)) stop("an interval cannot be shifted by another interval. Convert second interval to a period or duration.") interval(int@start + by, int_end(int) + by) } #' @description #' `int_overlaps()` tests if two intervals overlap. #' #' @rdname interval #' @param int1 an Interval object (for `int_overlaps()`, `int_aligns()`) #' @param int2 an Interval object (for `int_overlaps()`, `int_aligns()`) #' @return `int_overlaps()` -- logical, TRUE if int1 and int2 overlap by at #' least one second. FALSE otherwise #' @examples #' int1 <- interval(ymd("2001-01-01"), ymd("2002-01-01")) #' int2 <- interval(ymd("2001-06-01"), ymd("2002-06-01")) #' int3 <- interval(ymd("2003-01-01"), ymd("2004-01-01")) #' #' int_overlaps(int1, int2) # TRUE #' int_overlaps(int1, int3) # FALSE #' @export int_overlaps <- function(int1, int2) { stopifnot(c(is.interval(int1), is.interval(int2))) int1 <- int_standardize(int1) int2 <- int_standardize(int2) int1@start <= int2@start + int2@.Data & int2@start <= int1@start + int1@.Data } #' @description #' `int_standardize()` ensures all intervals in an interval object are #' positive. If an interval is not positive, flip it so that it retains its #' endpoints but becomes positive. #' #' @rdname interval #' @examples #' int <- interval(ymd("2002-01-01"), ymd("2001-01-01")) #' int_standardize(int) #' @export int_standardize <- function(int) { negs <- !is.na(int@.Data) & int@.Data < 0 int[negs] <- int_flip(int[negs]) int } #' @description #' `int_aligns()` tests if two intervals share an endpoint. The direction of #' each interval is ignored. int_align tests whether the earliest or latest #' moments of each interval occur at the same time. #' #' @rdname interval #' @return `int_aligns()` -- logical, TRUE if int1 and int2 begin or end on the #' same moment. FALSE otherwise #' @examples #' int1 <- interval(ymd("2001-01-01"), ymd("2002-01-01")) #' int2 <- interval(ymd("2001-06-01"), ymd("2002-01-01")) #' int3 <- interval(ymd("2003-01-01"), ymd("2004-01-01")) #' #' int_aligns(int1, int2) # TRUE #' int_aligns(int1, int3) # FALSE #' @export int_aligns <- function(int1, int2) { int1 <- int_standardize(int1) int2 <- int_standardize(int2) int1@start == int2@start | (int1@start + int1@.Data) == (int2@start + int2@.Data) } #' @description #' `int_diff()` returns the intervals that occur between the elements of a #' vector of date-times. `int_diff()` is similar to the POSIXt and Date #' methods of [diff()], but returns an [Interval-class] object instead #' of a difftime object. #' #' @rdname interval #' @param times A vector of POSIXct, POSIXlt or Date class date-times (for #' `int_diff()`) #' @return `int_diff()` -- interval object that contains the n-1 intervals #' between the n date-time in times #' @examples #' dates <- now() + days(1:10) #' int_diff(dates) #' @export int_diff <- function(times) { interval(times[-length(times)], times[-1]) } #' @export setGeneric("intersect") #' @export setMethod("intersect", signature(x = "Interval", y = "Interval"), function(x, y) { int1 <- int_standardize(x) int2 <- int_standardize(y) starts <- pmax(int1@start, int2@start) ends <- pmin(int1@start + int1@.Data, int2@start + int2@.Data) spans <- as.numeric(ends) - as.numeric(starts) no.int <- ends < starts no.int <- is.na(no.int) | no.int spans[no.int] <- NA starts[no.int] <- NA new.int <- new("Interval", spans, start = starts, tzone = x@tzone) negix <- !is.na(x@.Data) & (sign(x@.Data) == -1) new.int[negix] <- int_flip(new.int[negix]) new.int }) #' @export setGeneric("union") #' @export setMethod("union", signature(x = "Interval", y = "Interval"), function(x, y) { int1 <- int_standardize(x) int2 <- int_standardize(y) starts <- pmin(int1@start, int2@start) ends <- pmax(int1@start + int1@.Data, int2@start + int2@.Data) spans <- as.numeric(ends) - as.numeric(starts) if (any(!int_overlaps(int1, int2))) message("Union includes intervening time between intervals.") tz(starts) <- x@tzone new.int <- new("Interval", spans, start = starts, tzone = x@tzone) new.int[sign(x@.Data) == -1] <- int_flip(new.int[sign(x@.Data) == -1]) new.int }) #' @export setGeneric("setdiff") # returns the part of x that is not in y #' @export setMethod("setdiff", signature(x = "Interval", y = "Interval"), function(x, y) { if (length(x) != length(y)) { xy <- match_lengths(x, y) x <- xy[[1]] y <- xy[[2]] } aligned <- int_aligns(x, y) inside <- y %within% x makes2 <- !aligned & inside if (sum(makes2)) { stop(paste("Cases", which(makes2), "result in discontinuous intervals.")) } int1 <- int_standardize(x) int2 <- int_standardize(y) first.y <- int_start(int2) last.y <- int_end(int2) starts <- int_start(int1) starts[(last.y + 1) %within% int1] <- last.y[(last.y + 1) %within% int1] ends <- int_end(int1) ends[(first.y - 1) %within% int1] <- first.y[(first.y - 1) %within% int1] spans <- as.numeric(ends) - as.numeric(starts) new.int <- new("Interval", spans, start = starts, tzone = x@tzone) new.int[sign(x@.Data) == -1] <- int_flip(new.int[sign(x@.Data) == -1]) new.int }) #' Tests whether a date or interval falls within an interval #' #' %within% returns TRUE if `a` falls within interval `b`. Both `a` and `b` are #' recycled according to standard R rules. If `b` is a list of intervals, `a` is #' checked if it falls within any of the intervals in `b`. If a is an interval, #' both its start and end dates must fall within b to return TRUE. #' #' @export #' @rdname within-interval #' @aliases %within%,Interval,Interval-method %within%,ANY,Interval-method #' %within%,Date,list-method %within%,POSIXt,list-method #' @param a An interval or date-time object #' @param b An interval or a list of intervals (see examples) #' @return A logical #' @examples #' #' int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) #' int2 <- interval(ymd("2001-06-01"), ymd("2002-01-01")) #' #' ymd("2001-05-03") %within% int # TRUE #' int2 %within% int # TRUE #' ymd("1999-01-01") %within% int # FALSE #' #' ## recycling #' dates <- ymd(c("2014-12-20", "2014-12-30", "2015-01-01", "2015-01-03")) #' blackouts<- c(interval(ymd("2014-12-30"), ymd("2014-12-31")), #' interval(ymd("2014-12-30"), ymd("2015-01-03"))) #' dates %within% blackouts #' #' ## within ANY of the intervals of a list #' dates <- ymd(c("2014-12-20", "2014-12-30", "2015-01-01", "2015-01-03")) #' blackouts<- list(interval(ymd("2014-12-30"), ymd("2014-12-31")), #' interval(ymd("2014-12-30"), ymd("2015-01-03"))) #' dates %within% blackouts "%within%" <- function(a, b) standardGeneric("%within%") #' @export setGeneric("%within%") .within <- function(a, int) { as.numeric(a) - as.numeric(int@start) <= int@.Data & as.numeric(a) - as.numeric(int@start) >= 0 } setMethod("%within%", signature(b = "Interval"), function(a, b) { if (!is.instant(a)) stop("Argument 1 is not a recognized date-time") a <- as.POSIXct(a) .within(a, b) }) setMethod("%within%", signature(a = "Interval", b = "Interval"), function(a, b) { a <- int_standardize(a) b <- int_standardize(b) start.in <- as.numeric(a@start) >= as.numeric(b@start) end.in <- (as.numeric(a@start) + a@.Data) <= (as.numeric(b@start) + b@.Data) start.in & end.in }) setMethod("%within%", signature(a = "Interval", b = "Interval"), function(a, b) { a <- int_standardize(a) b <- int_standardize(b) start.in <- as.numeric(a@start) >= as.numeric(b@start) end.in <- (as.numeric(a@start) + a@.Data) <= (as.numeric(b@start) + b@.Data) start.in & end.in }) .within_instant <- function(a, b) { if (!all(sapply(b, is.interval))) stop("When second argument to %within% is a list it must contain interval objects only") a <- as.POSIXct(a) out <- FALSE for (int in b) { out <- out | .within(a, int) } out } setMethod("%within%", signature(a = "POSIXt", b = "list"), .within_instant) setMethod("%within%", signature(a = "Date", b = "list"), .within_instant) #' @export as.list.Interval <- function(x, ...) { lapply(seq_along(x), function(i) x[[i]]) } #' @export summary.Interval <- function(object, ...) { nas <- is.na(object) object <- object[!nas] n <- length(object) dates <- c(int_start(object), int_end(object)) earliest <- as.character(min(dates)) latest <- as.character(max(dates)) zone <- tz(dates) qq <- c(n, earliest, latest, zone) names(qq) <- c("Intervals", "Earliest endpoint", "Latest endpoint", "Time zone") if (any(nas)) c(qq, `NA's` = sum(nas)) else qq } #' @rdname time_length setMethod("time_length", signature("Interval"), function(x, unit = "second") { unit <- standardise_period_names(unit) if (unit %in% c("year", "month")) { periods <- as.period(x, unit = unit) int_part <- slot(periods, unit) prev_aniv <- add_with_rollback( int_start(x), (int_part * period(1, units = unit)), roll_to_first = TRUE, preserve_hms = FALSE) next_aniv <- add_with_rollback( int_start(x), ((int_part + ifelse(x@.Data < 0, -1, 1)) * period(1, units = unit)), roll_to_first = TRUE, preserve_hms = FALSE) sofar <- as.duration(int_end(x) - prev_aniv) total <- as.duration(next_aniv - prev_aniv) int_part + sign(x@.Data) * sofar / total } else { as.duration(x) / duration(num = 1, units = unit) } }) #' @export setMethod("Arith", signature(e1 = "Interval", e2 = "ANY"), undefined_arithmetic) #' @export setMethod("Arith", signature(e1 = "ANY", e2 = "Interval"), undefined_arithmetic) #' @name hidden_aliases #' @aliases Arith,Interval,ANY-method Arith,ANY,Interval-method #' intersect,Interval,Interval-method union,Interval,Interval-method #' setdiff,Interval,Interval-method as.numeric,Interval-method #' show,Interval-method c,Interval-method rep,Interval-method #' [,Interval-method [<-,Interval,ANY,ANY,ANY-method [[,Interval-method #' [[<-,Interval,ANY,ANY,ANY-method $,Interval-method $<-,Interval-method #' as.difftime,Interval-method as.character,Interval-method #' +,Interval,Duration-method +,Interval,Interval-method #' +,Interval,Period-method +,Interval,Date-method +,Date,Interval-method #' +,Interval,difftime-method +,difftime,Interval-method #' +,Interval,numeric-method +,numeric,Interval-method #' +,Interval,POSIXct-method +,POSIXct,Interval-method #' +,Interval,POSIXlt-method +,POSIXlt,Interval-method #' /,Interval,Duration-method /,Interval,Interval-method #' /,Interval,Period-method /,Interval,difftime-method #' /,difftime,Interval-method /,Interval,numeric-method #' /,numeric,Interval-method *,Interval,ANY-method *,ANY,Interval-method #' -,Interval,missing-method -,Interval,Interval-method -,Date,Interval-method #' -,POSIXct,Interval-method -,POSIXlt,Interval-method #' -,numeric,Interval-method -,Interval,Date-method -,Interval,POSIXct-method #' -,Interval,POSIXlt-method -,Interval,numeric-method #' -,Duration,Interval-method -,Period,Interval-method #' %%,Interval,Duration-method %%,Interval,Interval-method #' %%,Interval,Period-method %%,Interval,Duration %%,Interval,Interval #' %%,Interval,Period -,Date,Interval -,Duration,Interval -,Interval,Date #' -,Interval,Interval -,Interval,POSIXct -,Interval,POSIXlt #' -,Interval,numeric -,POSIXct,Interval -,POSIXlt,Interval -,numeric,Interval NULL lubridate/R/accessors-tz.r0000644000176200001440000000560413263121132015230 0ustar liggesusers#' Get/set time zone component of a date-time #' #' Time zones are stored as character strings in an #' attribute of date-time objects. tz returns a date's time zone attribute. #' When used as a settor, it changes the time zone attribute. R does not come with #' a predefined list zone names, but relies on the user's OS to interpret time zone #' names. As a result, some names will be recognized on some computers but not others. #' Most computers, however, will recognize names in the timezone data base originally #' compiled by Arthur Olson. These names normally take the form "Country/City." A #' convenient listing of these timezones can be found at #' \url{http://en.wikipedia.org/wiki/List_of_tz_database_time_zones}. #' #' Setting tz does not update a date-time to display the same moment as measured #' at a different time zone. See [with_tz()]. Setting a new time zone #' creates a new date-time. The numerical value of the hours element stays the #' same, only the time zone attribute is replaced. This creates a new date-time #' that occurs an integer value of hours before or after the original date-time. #' #' If x is of a class that displays all date-times in the GMT timezone, such as #' chron, then R will update the number in the hours element to display the new #' date-time in the GMT timezone. #' #' For a description of the time zone attribute, see [base::timezones()] #' or [base::DateTimeClasses]. #' #' @export #' @param x a date-time object of class a POSIXct, POSIXlt, Date, chron, yearmon, #' yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, fts or anything else that can #' be coerced to POSIXlt with as.POSIXlt #' @return the first element of x's tzone attribute vector as a character string. If no tzone #' attribute exists, tz returns "GMT". #' @keywords utilities manip chron methods #' @examples #' x <- ymd("2012-03-26") #' tz(x) #' tz(x) <- "GMT" #' x #' \dontrun{ #' tz(x) <- "America/New_York" #' x #' tz(x) <- "America/Chicago" #' x #' tz(x) <- "America/Los_Angeles" #' x #' tz(x) <- "Pacific/Honolulu" #' x #' tz(x) <- "Pacific/Auckland" #' x #' tz(x) <- "Europe/London" #' x #' tz(x) <- "Europe/Berlin" #' x #' #' Sys.setenv(TZ = "UTC") #' now() #' tz(now()) #' Sys.unsetenv("TZ") #' } tz <- function (x) UseMethod("tz") #' @export tz.default <- function(x) { tzone <- attr(x, "tzone")[[1]] if (is.null(tzone) && !is.POSIXt(x)) return("UTC") if (is.character(tzone) && nzchar(tzone)) return(tzone) tzone <- attr(as.POSIXlt(x[1]), "tzone")[[1]] if (is.null(tzone)) return("UTC") tzone } #' @export tz.zoo <- function(x) { attr(as.POSIXlt(zoo::index(x)), "tzone")[[1]] } #' @export tz.timeSeries <- function(x) x@FinCenter #' @export tz.irts <- function(x) return("GMT") #' @rdname tz #' @param value timezone value to be assigned to `x`'s `tzone` attribute #' @export "tz<-" <- function(x, value) { new <- force_tz(x, value) reclass_date(new, x) } lubridate/vignettes/0000755000176200001440000000000013263152652014242 5ustar liggesuserslubridate/vignettes/lubridate.Rmd0000644000176200001440000002051013201152061016641 0ustar liggesusers--- title: "Do more with dates and times in R" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Do more with dates and times in R} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(comment = "#>", collapse = TRUE) ``` (This vignette is an updated version of the blog post first published at [r-statistics](http://www.r-statistics.com/2012/03/do-more-with-dates-and-times-in-r-with-lubridate-1-1-0/)_ Lubridate is an R package that makes it easier to work with dates and times. Below is a concise tour of some of the things lubridate can do for you. Lubridate was created by Garrett Grolemund and Hadley Wickham, and is now maintained by Vitalie Spinu. ## Parsing dates and times Getting R to agree that your data contains the dates and times you think it does can be tricky. Lubridate simplifies that. Identify the order in which the year, month, and day appears in your dates. Now arrange "y", "m", and "d" in the same order. This is the name of the function in lubridate that will parse your dates. For example, ```{r} library(lubridate) ymd("20110604") mdy("06-04-2011") dmy("04/06/2011") ``` Lubridate's parse functions handle a wide variety of formats and separators, which simplifies the parsing process. If your date includes time information, add h, m, and/or s to the name of the function. `ymd_hms` is probably the most common date time format. To read the dates in with a certain time zone, supply the official name of that time zone in the `tz` argument. ```{r} arrive <- ymd_hms("2011-06-04 12:00:00", tz = "Pacific/Auckland") arrive leave <- ymd_hms("2011-08-10 14:00:00", tz = "Pacific/Auckland") leave ``` ## Setting and Extracting information Extract information from date times with the functions `second`, `minute`, `hour`, `day`, `wday`, `yday`, `week`, `month`, `year`, and `tz`. You can also use each of these to set (i.e, change) the given information. Notice that this will alter the date time. `wday` and `month` have an optional `label` argument, which replaces their numeric output with the name of the weekday or month. ```{r} second(arrive) second(arrive) <- 25 arrive second(arrive) <- 0 wday(arrive) wday(arrive, label = TRUE) ``` ## Time Zones There are two very useful things to do with dates and time zones. First, display the same moment in a different time zone. Second, create a new moment by combining an existing clock time with a new time zone. These are accomplished by `with_tz` and `force_tz`. For example, a while ago I was in Auckland, New Zealand. I arranged to meet the co-author of lubridate, Hadley, over skype at 9:00 in the morning Auckland time. What time was that for Hadley who was back in Houston, TX? ```{r} meeting <- ymd_hms("2011-07-01 09:00:00", tz = "Pacific/Auckland") with_tz(meeting, "America/Chicago") ``` So the meetings occurred at 4:00 Hadley's time (and the day before no less). Of course, this was the same actual moment of time as 9:00 in New Zealand. It just appears to be a different day due to the curvature of the Earth. What if Hadley made a mistake and signed on at 9:00 his time? What time would it then be my time? ```{r} mistake <- force_tz(meeting, "America/Chicago") with_tz(mistake, "Pacific/Auckland") ``` His call would arrive at 2:00 am my time! Luckily he never did that. ## Time Intervals You can save an interval of time as an Interval class object with lubridate. This is quite useful! For example, my stay in Auckland lasted from June 4, 2011 to August 10, 2011 (which we've already saved as arrive and leave). We can create this interval in one of two ways: ```{r} auckland <- interval(arrive, leave) auckland auckland <- arrive %--% leave auckland ``` My mentor at the University of Auckland, Chris, traveled to various conferences that year including the Joint Statistical Meetings (JSM). This took him out of the country from July 20 until the end of August. ```{r} jsm <- interval(ymd(20110720, tz = "Pacific/Auckland"), ymd(20110831, tz = "Pacific/Auckland")) jsm ``` Will my visit overlap with and his travels? Yes. ```{r} int_overlaps(jsm, auckland) ``` Then I better make hay while the sun shines! For what part of my visit will Chris be there? ```{r} setdiff(auckland, jsm) ``` Other functions that work with intervals include `int_start`, `int_end`, `int_flip`, `int_shift`, `int_aligns`, `union`, `intersect`, `setdiff`, and `%within%`. ## Arithmetic with date times Intervals are specific time spans (because they are tied to specific dates), but lubridate also supplies two general time span classes: Durations and Periods. Helper functions for creating periods are named after the units of time (plural). Helper functions for creating durations follow the same format but begin with a "d" (for duration) or, if you prefer, and "e" (for exact). ```{r} minutes(2) ## period dminutes(2) ## duration ``` Why two classes? Because the timeline is not as reliable as the number line. The Duration class will always supply mathematically precise results. A duration year will always equal 365 days. Periods, on the other hand, fluctuate the same way the timeline does to give intuitive results. This makes them useful for modeling clock times. For example, durations will be honest in the face of a leap year, but periods may return what you want: ```{r} leap_year(2011) ## regular year ymd(20110101) + dyears(1) ymd(20110101) + years(1) leap_year(2012) ## leap year ymd(20120101) + dyears(1) ymd(20120101) + years(1) ``` You can use periods and durations to do basic arithmetic with date times. For example, if I wanted to set up a reoccuring weekly skype meeting with Hadley, it would occur on: ```{r} meetings <- meeting + weeks(0:5) ``` Hadley travelled to conferences at the same time as Chris. Which of these meetings would be affected? The last two. ```{r} meetings %within% jsm ``` How long was my stay in Auckland? ```{r} auckland / ddays(1) auckland / ddays(2) auckland / dminutes(1) ``` And so on. Alternatively, we can do modulo and integer division. Sometimes this is more sensible than division - it is not obvious how to express a remainder as a fraction of a month because the length of a month constantly changes. ```{r} auckland %/% months(1) auckland %% months(1) ``` Modulo with an timespan returns the remainder as a new (smaller) interval. You can turn this or any interval into a generalized time span with `as.period`. ```{r} as.period(auckland %% months(1)) as.period(auckland) ``` ### If anyone drove a time machine, they would crash The length of months and years change so often that doing arithmetic with them can be unintuitive. Consider a simple operation, `January 31st + one month`. Should the answer be 1. `February 31st` (which doesn't exist) 2. `March 4th` (31 days after January 31), or 3. `February 28th` (assuming its not a leap year) A basic property of arithmetic is that `a + b - b = a`. Only solution 1 obeys this property, but it is an invalid date. I've tried to make lubridate as consistent as possible by invoking the following rule *if adding or subtracting a month or a year creates an invalid date, lubridate will return an NA*. This is new with version 1.3.0, so if you're an old hand with lubridate be sure to remember this! If you thought solution 2 or 3 was more useful, no problem. You can still get those results with clever arithmetic, or by using the special `%m+%` and `%m-%` operators. `%m+%` and `%m-%` automatically roll dates back to the last day of the month, should that be necessary. ```{r} jan31 <- ymd("2013-01-31") jan31 + months(0:11) floor_date(jan31, "month") + months(0:11) + days(31) jan31 %m+% months(0:11) ``` Notice that this will only affect arithmetic with months (and arithmetic with years if your start date it Feb 29). ## Vectorization The code in lubridate is vectorized and ready to be used in both interactive settings and within functions. As an example, I offer a function for advancing a date to the last day of the month ```{r} last_day <- function(date) { ceiling_date(date, "month") - days(1) } ``` ## Further Resources To learn more about lubridate, including the specifics of periods and durations, please read the [original lubridate paper](http://www.jstatsoft.org/v40/i03/). Questions about lubridate can be addressed to the lubridate google group. Bugs and feature requests should be submitted to the [lubridate development page](http://github.com/hadley/lubridate) on github. lubridate/README.md0000644000176200001440000000630413263140530013504 0ustar liggesusers lubridate ========================================================== [![Build Status](https://travis-ci.org/tidyverse/lubridate.svg?branch=master)](https://travis-ci.org/tidyverse/lubridate) [![Coverage Status](https://codecov.io/gh/tidyverse/lubridate/branch/master/graph/badge.svg)](https://codecov.io/gh/tidyverse/lubridate) [![CRAN RStudio mirror downloads](http://cranlogs.r-pkg.org/badges/lubridate)](https://cran.r-project.org/package=lubridate) [![Development version](https://img.shields.io/badge/devel-1.6.0.9000-orange.svg)](https://github.com/tidyverse/lubridate) [![CRAN version](http://www.r-pkg.org/badges/version/lubridate)](https://cran.r-project.org/package=lubridate) Overview -------- Date-time data can be frustrating to work with in R. R commands for date-times are generally unintuitive and change depending on the type of date-time object being used. Moreover, the methods we use with date-times must be robust to time zones, leap days, daylight savings times, and other time related quirks, and R lacks these capabilities in some situations. Lubridate makes it easier to do the things R does with date-times and possible to do the things R does not. If you are new to lubridate, the best place to start is the [date and times chapter](http://r4ds.had.co.nz/dates-and-times.html) in R for data science. Installation ------------ ``` r # The easiest way to get lubridate is to install the whole tidyverse: install.packages("tidyverse") # Alternatively, install just lubridate: install.packages("lubridate") # Or the the development version from GitHub: # install.packages("devtools") devtools::install_github("tidyverse/lubridate") ``` Features -------- - Easy and fast parsing of date-times: `ymd()`, `ymd_hms`, `dmy()`, `dmy_hms`, `mdy()`, ... ``` r ymd(20101215) #> [1] "2010-12-15" mdy("4/1/17") #> [1] "2017-04-01" ``` - Simple functions to get and set components of a date-time, such as `year()`, `month()`, `mday()`, `hour()`, `minute()` and `second()`: ``` r bday <- dmy("14/10/1979") month(bday) #> [1] 10 wday(bday, label = TRUE) #> [1] Sun #> Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat year(bday) <- 2016 wday(bday, label = TRUE) #> [1] Fri #> Levels: Sun < Mon < Tue < Wed < Thu < Fri < Sat ``` - Helper functions for handling time zones: `with_tz()`, `force_tz()` ``` r time <- ymd_hms("2010-12-13 15:30:30") time #> [1] "2010-12-13 15:30:30 UTC" # Changes printing with_tz(time, "America/Chicago") #> [1] "2010-12-13 09:30:30 CST" # Changes time force_tz(time, "America/Chicago") #> [1] "2010-12-13 15:30:30 CST" ``` Lubridate also expands the type of mathematical operations that can be performed with date-time objects. It introduces three new time span classes borrowed from . - `durations`, which measure the exact amount of time between two points - `periods`, which accurately track clock times despite leap years, leap seconds, and day light savings time - `intervals`, a protean summary of the time information between two points lubridate/MD50000644000176200001440000002373613263357253012561 0ustar liggesusers210667b3b39d03c982e3bb3d63706695 *DESCRIPTION c1a1cf735e19acd65dccb75f0a169aea *NAMESPACE 3f1c84dd9b46eb8389f77c7fdac9e886 *NEWS.md d72f2565ad7238ec4a79d278b371d039 *R/Dates.r 3cf090356e47090853b4172cfe50bea4 *R/POSIXt.r 87868c8a1e291ada05071f80e21e9d8e *R/RcppExports.R c862f09386cea352d94c20c1c17545ed *R/accessors-date.R c4e7b6cb0a72a59165699ff5095c44b0 *R/accessors-day.r ecbde6df1e4c40e809cc628374a2d600 *R/accessors-dst.r 1313b29734efe4f590509e6b81c2d6fe *R/accessors-hour.r 2eb53830f5b2a2b2c5aad31fde018adf *R/accessors-minute.r 38045ee40fc05d94761f53d973e5f0e6 *R/accessors-month.r d3f6cc71e962338b29eafdb18c6da0d9 *R/accessors-quarter.r ce5cdf6f241ea8051c773e00a698032b *R/accessors-second.r 406affed06f21439aa34bd77fc36d83e *R/accessors-tz.r d3eb299bcada39c5f379471475f074c7 *R/accessors-week.r 42f2a9a6f6bb0b62c78d00b7d40206c0 *R/accessors-year.r 61df9d1deda71da55ce1a569680fc4d3 *R/am-pm.r 485e265728c9f4e1a73e1b42a789e51f *R/coercion.r 761d023ca4f74330258c68d3b37067c1 *R/constants.r 6922e15119548c547037189255058c33 *R/data.r acd9ce16dd804b620388df1537719ddc *R/decimal-dates.r 4de05fbab296d5441cc20057abd46abc *R/deprecated.r 1a451b7631c3991b065487df98676362 *R/difftimes.r 2b38f69a8e9dec95e696e5631dd94e19 *R/durations.r 57f65d777ecff879f1f01a0b77126f62 *R/guess.r fe1b2df9042ccf14f76f1eb981938db7 *R/hidden.r 5b456d9d7cc47c1a62f7e7cd9ff55036 *R/instants.r bf6414333b29cc8f85dd369eac6863c8 *R/intervals.r bc1784ed0ba16223d62dc7a707194470 *R/leap-years.r 6168a35c3e2c9b4a50045c53cbb7bec8 *R/numeric.r 71e3f0f4838d0d7f19374480c353c12c *R/ops-addition.r 57f09af09cfd615b1a1753b411cfd439 *R/ops-compare.r 17256ee0147d76a4e718862f29ec0dc9 *R/ops-division.r 69869c3f8b13464c27a33dcfd1250d2d *R/ops-integer-division.r 102ae8a9642e5102452f7ce8f606f41b *R/ops-m+.r 9b4df9b4252ba44fe2e2e07d9d3e7dd8 *R/ops-modulo.r 447177184ba0f06017650fdcc24b4c88 *R/ops-multiplication.r d90b405e2cdb72b4c30481c9271e23d7 *R/ops-subtraction.r 037b3ec6ce00749a37590f6222dbd80c *R/package.r ff8a75d7daad5f1f427a74d235ecd64f *R/parse.r e7f69d16db336534222e9ab23d044f34 *R/periods.r bc9405cd2758841c05511f95e771bf8d *R/pretty.r 6595a37f5802b65fb4342eed4fbc6914 *R/round.r 5c233f64573df7b9bf0238ce937d916b *R/stamp.r 3ba08b2ba581c15a88fa69eac1f96756 *R/time-zones.r 8e0e2312b49f39d8afe6b1bc96c0791e *R/timespans.r 24a2cd25e95450e1605bf1ea3aee93ae *R/update.r 2e3ba41d4b7fbafdbe0e2a78aa52253f *R/util.r 22aeb48a32a9ecad2ab22dfeaae427f7 *R/zzz.R 34aaa7d81fc3531299f7ee1a58249c11 *README.md 7945da974e4573cba2297d9a261b6353 *build/vignette.rds 6377a8922f467e256c37973dcacb488a *cleanup a4eca0d1ebff1dc90da52f32fef3de56 *data/lakers.rda 8d4280470088183c93d3b05394f49074 *inst/CITATION 305e9bb0edf2b9f339192932ade0bf4b *inst/cctz.sh 81cc7d37c6618a2ac39c1daa127e948f *inst/doc/lubridate.R e6555ea369c5001f01e9365009996e5e *inst/doc/lubridate.Rmd 6e02f1b15809177f6c6ee1a0f01817f5 *inst/doc/lubridate.html cbd0115223b55d1d4e6b1b9084872104 *inst/pkgdown/assets/tidyverse.css 1b382473f33def546c7c664480b005f6 *inst/pkgdown/assets/tidyverse.css.map 83324230ad6f187a6552678d48044df7 *man/DateCoercion.Rd 1c744e6fea1fe993f53b01504366e3cb *man/DateTimeUpdate.Rd ae9023e9f588f68d95d680d14ab14d7e *man/Deprecated.Rd 75d6bb5c9fdb4e2470d261b28016b5b5 *man/Duration-class.Rd c2905e638e7e28bcab806cbc415ee827 *man/Interval-class.Rd ee5a270307fe8479316b48556d08d627 *man/Period-class.Rd 8444c3b347ff1b0c8539859afa67f43c *man/Timespan-class.Rd f0d7a599451acc1e310393135231ce49 *man/am.Rd b0896c1ca8a015375809333e5e9377ed *man/as.duration.Rd 82f8ca0cc720c261aab1fe6e98bab89c *man/as.interval.Rd a16e11f5ad9c1ab9263fe907f7ad9fff *man/as.period.Rd 3baadb0f2de622f4d6f4444ab1d8fb15 *man/as_date.Rd 2148aa665079aa6473b3234ed95fd69b *man/date.Rd 47a209eb20e5fbb24d85c878518384f6 *man/date_decimal.Rd 9f975c83238b42878316b8587368404c *man/day.Rd 284797346f45c0bf3c15fa174a06570b *man/days_in_month.Rd 1871b00c7cd5bc8f778fa2833166a77d *man/decimal_date.Rd 607c352a5b278a15526f223dedd7c066 *man/dst.Rd 0e65acfaf876407a95e2fc0d3deaaa8f *man/duration.Rd 68349cce281ef8ef965844cf20429f13 *man/figures/logo.png d0f446802c69f562cb09a7c579ec3148 *man/fit_to_timeline.Rd 91320e7165f869e5230888c71036040b *man/force_tz.Rd ed36d77f110d9d290ab40e203a7f07c3 *man/guess_formats.Rd 8945d3ece6c03817f954b25adb675074 *man/hidden_aliases.Rd a2bca99c3614d7ad55dc8ac6ec7f09da *man/hms.Rd dbafcee71dd1b05550e538163cfd0a22 *man/hour.Rd 082f67ce9660f09cf00aeda94701c8dc *man/interval.Rd 71cd3381e21feeca4fde8565258f4f5d *man/is.Date.Rd d68462512d1b951f44779c66867b6d9f *man/is.POSIXt.Rd c36e9c3670d8c532c244acfea2b60036 *man/is.difftime.Rd ee069c832b32e18a71b3d357d5ecf304 *man/is.instant.Rd 56d9071aac41d2c0f53242caa1aba68f *man/is.timespan.Rd b097339c144333564b23a885cb945734 *man/lakers.Rd bca4c2d33002b53f467c4b54b1592fa2 *man/leap_year.Rd 78b4373e5ea296fd96bcea1708c096cf *man/local_time.Rd 8c4925f3439bd879b5a6fbdae611a56f *man/lubridate-package.Rd 5afff9614d9b476edf87505537395b0d *man/make_datetime.Rd 40751095081f29257bc309ec593e9c33 *man/make_difftime.Rd 891b351972ef9452d6d5e84fab299143 *man/minute.Rd 53a5d11c413fb3bd44382eb39e0ea6b6 *man/month.Rd edcdea2ee436ad4baed2fd0c7008b4ea *man/mplus.Rd bb1f23f07f3299ead3303b6a5c6b4823 *man/now.Rd 5941653a60a360ccd073660a6dd9afe6 *man/origin.Rd 7e4b834db024b08be1e5457c15e2facd *man/parse_date_time.Rd f8ad958e2fe2814e1750bb06b9c622bd *man/period.Rd b9ec23d56e3ccfbae6c5cb94d3ac307a *man/period_to_seconds.Rd a10dd35669904ea6eb1e58244e9687c1 *man/pretty_dates.Rd a0ba6f9dc53c632096dbc2e93591d15b *man/quarter.Rd e3705cefb2582b6a2052bde98c4e5282 *man/reclass_date.Rd 81ce1849f78d9a1bf155c9170c1211f6 *man/reclass_timespan.Rd 7459de1d35ea66cc396339eefa0e1f42 *man/rollback.Rd bc32f4b562f7029dc5d121a039bcaaa6 *man/round_date.Rd fdb1adcbbf93056d9f59e9ac99c0973f *man/second.Rd 298aeac11e27a33f158c3cfbb85035a7 *man/stamp.Rd b554f7b488606d65a6d3e686bcfc61c0 *man/time_length.Rd 738e49f3c98c6dcf319c7c2ab8b0442f *man/timespan.Rd 986079ca02b48250948b7ff7f8e43efb *man/today.Rd 0a278c2030e240e9265e31e3b6a69a5d *man/tz.Rd 8777d6369482b9f23c419627be36b54d *man/week.Rd 488770c9da8e6724c2162c3cae66e36c *man/with_tz.Rd 4e834f12165f867e83b7fc6a53417954 *man/within-interval.Rd 42469bfbb8c9c03e19bb0696b17771f1 *man/year.Rd c247aa8b77fa80aa9aad8bb8f8152ffe *man/ymd.Rd 1c3a87823a730ce604568dd767e3eab2 *man/ymd_hms.Rd d98ecb14ceabf6fa8a5aa0a9c7056eac *po/R-it.po 81e173ba04b6f167d6f73ef0ab07920a *po/R-ko.po 04a768e668f156d1f50982995cf05b88 *po/R-lubridate.pot e6969607eb9a6134eea082a9eb6901b6 *src/Makevars 39489a407f59f45f81e260e310c288e3 *src/RcppExports.cpp 1afbb7e22acc51f95e1a76628a699964 *src/cctz/include/civil_time.h 5d8bbb766d229ba76c8b755949e60fd6 *src/cctz/include/civil_time_detail.h 54123a9d70802660ddb19b1927f6c504 *src/cctz/include/time_zone.h ac5cd74e131a45fd6e02b6f405e635ca *src/cctz/include/zone_info_source.h a2bcc1e878160cddec1a04368f66e716 *src/cctz/src/time_zone_fixed.cc 2dfe7665213c143331348215c68c6a7a *src/cctz/src/time_zone_fixed.h 14e7b0462bad418e70a7a020865aaba0 *src/cctz/src/time_zone_if.cc 65a52860923e4977d05ba3c623d91573 *src/cctz/src/time_zone_if.h b0ae3a188ff871de4e471a5828638476 *src/cctz/src/time_zone_impl.cc 1e7f3af5ea6208c64d91247f216e3fe9 *src/cctz/src/time_zone_impl.h fc185d5bbe4361a966352791f6339251 *src/cctz/src/time_zone_info.cc 96ebf017af78cb0ba038d49c05b8117b *src/cctz/src/time_zone_info.h d88f667730f32db947cafbc0d7f0242c *src/cctz/src/time_zone_libc.cc c659e34863285c3152f3f0e9fc91bb83 *src/cctz/src/time_zone_libc.h 52434b272d1c8fd95088d88e1d37e3a7 *src/cctz/src/time_zone_lookup.cc d1bbbebbd83e6ee142ce5e9f0a04bfaa *src/cctz/src/time_zone_lookup_test.cc 6c18c8d0b18bd20e7bcb28289ae661e0 *src/cctz/src/time_zone_posix.cc fb5037d3e88fe91e9d4bf6ed96d2d1c1 *src/cctz/src/time_zone_posix.h 5ce2d52b3475725287cbcba308f10ee2 *src/cctz/src/tzfile.h ef3ab1e7a2c198cc0138d88f83738ab2 *src/constants.h 2b4db9e0c0ec0554a02c53d0208508b0 *src/datetime.c 211b40cee85236352e63759e338e9d50 *src/period.c a3ac600f87e36ab992a96ec76e6d7864 *src/tparse.c 14a0f49efb75dbe0d8b73d62afec54c7 *src/update.cpp b2f5f76a149423c7aba089cde07beb32 *src/utils.c 10cac4a44d2f0904c82e04c51c5fd714 *src/utils.h 2341ad901c9e60c8555fe5eaee09e787 *tests/testthat.R e83af8385b1dd2e086d8baa81762d39b *tests/testthat/test-Dates.R 858693fafcc6a81dc79d611127ab22e9 *tests/testthat/test-POSIXt.R ecea9198870dfc3f2d5258a3cdc22bd2 *tests/testthat/test-accessors.R a0e8f9a736b7842ae348c436aa6e3c44 *tests/testthat/test-am-pm.R 7a312d36f8179239f4f33d45dc16c120 *tests/testthat/test-daylight-savings.R c5fb572487ee854798eddecb31110030 *tests/testthat/test-decimal-date.R 061823d9cfc6aab9d526e012af7da723 *tests/testthat/test-difftimes.R 026eaf8804b8353daf35ea29cd4fc4a7 *tests/testthat/test-durations.R 8e8a55e39e4bcb93233dc9d483d03d62 *tests/testthat/test-guess.R be42f054c34fe49f85fb9c1335a56998 *tests/testthat/test-instants.R 54e57c42b85aa94a39fc8916cd226cba *tests/testthat/test-intervals.R c1717c6fb3c225342fed6f9fea199508 *tests/testthat/test-namespace.R 40eaef41f8beb260c482a1eb7a6edfba *tests/testthat/test-ops-addition.R bf6b1ed44c385170ef59c51044366092 *tests/testthat/test-ops-compare.R 0c11158568136165dd53a29af6bc2497 *tests/testthat/test-ops-division.R fb6d8654f1674894a7f32c17ea6cae5d *tests/testthat/test-ops-integer-division.R 3e2a469d276593f2ace66f8aa75f0958 *tests/testthat/test-ops-modulo.R dac064c7d3a528c7f4ab4261c556f469 *tests/testthat/test-ops-multiplication.R c132b8441a0948250c4b964411309627 *tests/testthat/test-ops-subtraction.R 6cde267e91dacc9f9bf48cf73b351a5f *tests/testthat/test-parsers.R ae8f382b2b91dfb1ce36bc71506b6ee9 *tests/testthat/test-periods.R 294cb3f1ed29552dfde47635031dd740 *tests/testthat/test-pretty.R 70964d2d3d93a481c6e3ef66fe64fc70 *tests/testthat/test-rollback.R b774382f6a7b97a0bf3a647daf63780a *tests/testthat/test-round.R a26ea55f748dc6d1d241271d43c34c4f *tests/testthat/test-settors.R c62cc0f8af40d90766fb236f7bf726c9 *tests/testthat/test-stamp.R 8dba9113b1df8d775e9cdb71982fe6cb *tests/testthat/test-timespans.R 3d57367cd2a45554521dab634da9fef7 *tests/testthat/test-timezones.R 9becb1b2d665df7492fb04682ad3e458 *tests/testthat/test-update.R dd24b10456b2c43c826ec5138e16d8cd *tests/testthat/test-utilities.R e6555ea369c5001f01e9365009996e5e *vignettes/lubridate.Rmd lubridate/build/0000755000176200001440000000000013263152652013331 5ustar liggesuserslubridate/build/vignette.rds0000644000176200001440000000033413263152652015670 0ustar liggesusersmQ0  T0~`_Ax1ă)3,` 旋EA]׾nbꂧ l fxz2FDi&XQiirցjˌY@$K"[-7Bh _7cnɡcqe]?Q[qk*=p&Yqw/@wq҇V5ԟtD Awp-, for more details. Authors@R: c( person("Vitalie", "Spinu", email = "spinuvit@gmail.com", role = c("aut","cre")), person("Garrett", "Grolemund", role = "aut"), person("Hadley", "Wickham", role = "aut"), person("Ian", "Lyttle", role="ctb"), person("Imanuel", "Constigan", role = "ctb"), person("Jason", "Law", role="ctb"), person("Doug","Mitarotonda", role="ctb"), person("Joseph", "Larmarange", role="ctb"), person("Jonathan", "Boiser", role="ctb"), person("Chel Hee", "Lee", role = "ctb") ) Maintainer: Vitalie Spinu License: GPL (>= 2) Depends: methods, R (>= 3.0.0) Imports: stringr, Rcpp (>= 0.12.13), LinkingTo: Rcpp, Suggests: testthat, knitr, covr Enhances: chron, fts, timeSeries, timeDate, tis, tseries, xts, zoo SystemRequirements: A system with zoneinfo data (e.g. /usr/share/zoneinfo) as well as a recent-enough C++11 compiler (such as g++-4.8 or later). On Windows the zoneinfo included with R is used. VignetteBuilder: knitr LazyData: true Collate: 'Dates.r' 'POSIXt.r' 'RcppExports.R' 'util.r' 'parse.r' 'timespans.r' 'intervals.r' 'difftimes.r' 'durations.r' 'periods.r' 'accessors-date.R' 'accessors-day.r' 'accessors-dst.r' 'accessors-hour.r' 'accessors-minute.r' 'accessors-month.r' 'accessors-quarter.r' 'accessors-second.r' 'accessors-tz.r' 'accessors-week.r' 'accessors-year.r' 'am-pm.r' 'time-zones.r' 'numeric.r' 'coercion.r' 'constants.r' 'data.r' 'decimal-dates.r' 'deprecated.r' 'guess.r' 'hidden.r' 'instants.r' 'leap-years.r' 'ops-addition.r' 'ops-compare.r' 'ops-division.r' 'ops-integer-division.r' 'ops-m+.r' 'ops-modulo.r' 'ops-multiplication.r' 'ops-subtraction.r' 'package.r' 'pretty.r' 'round.r' 'stamp.r' 'update.r' 'zzz.R' RoxygenNote: 6.0.1 URL: http://lubridate.tidyverse.org, https://github.com/tidyverse/lubridate BugReports: https://github.com/tidyverse/lubridate/issues NeedsCompilation: yes Packaged: 2018-04-10 15:18:02 UTC; vspinu Author: Vitalie Spinu [aut, cre], Garrett Grolemund [aut], Hadley Wickham [aut], Ian Lyttle [ctb], Imanuel Constigan [ctb], Jason Law [ctb], Doug Mitarotonda [ctb], Joseph Larmarange [ctb], Jonathan Boiser [ctb], Chel Hee Lee [ctb] Repository: CRAN Date/Publication: 2018-04-11 10:08:43 UTC lubridate/man/0000755000176200001440000000000013263116135013001 5ustar liggesuserslubridate/man/dst.Rd0000644000176200001440000000132713201152061014053 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-dst.r \name{dst} \alias{dst} \title{Get \strong{d}aylight \strong{s}avings \strong{t}ime indicator of a date-time} \usage{ dst(x) } \arguments{ \item{x}{a date-time object} } \value{ A logical. TRUE if DST is in force, FALSE if not, NA if unknown. } \description{ Date-time must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. } \details{ A date-time's daylight savings flag can not be set because it depends on the date-time's year, month, day, and hour values. } \examples{ x <- ymd("2012-03-26") dst(x) } \keyword{chron} \keyword{methods} \keyword{utilities} lubridate/man/timespan.Rd0000644000176200001440000000262113201152061015077 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/timespans.r \name{timespan} \alias{timespan} \alias{timespans} \title{Description of time span classes in lubridate} \description{ A time span can be measured in three ways: as a duration, an interval, or a period. \itemize{ \item \link{duration}s record the exact number of seconds in a time span. They measure the exact passage of time but do not always align with human measurements like hours, months and years. \item \link{period}s record the change in the clock time between two date-times. They are measured in human units: years, months, days, hours, minutes, and seconds. \item \link{intervals} are time spans bound by two real date-times. Intervals can be accurately converted to periods and durations. } } \examples{ duration(3690, "seconds") period(3690, "seconds") period(second = 30, minute = 1, hour = 1) interval(ymd_hms("2009-08-09 13:01:30"), ymd_hms("2009-08-09 12:00:00")) date <- ymd_hms("2009-03-08 01:59:59") # DST boundary date + days(1) date + ddays(1) date2 <- ymd_hms("2000-02-29 12:00:00") date2 + years(1) # self corrects to next real day date3 <- ymd_hms("2009-01-31 01:00:00") date3 + c(0:11) * months(1) span <- date2 \%--\% date #creates interval date <- ymd_hms("2009-01-01 00:00:00") date + years(1) date - days(3) + hours(6) date + 3 * seconds(10) months(6) + days(1) } \keyword{chron} \keyword{classes} lubridate/man/year.Rd0000644000176200001440000000200113201152061014207 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-year.r \name{year} \alias{year} \alias{year<-} \alias{isoyear} \alias{epiyear} \title{Get/set years component of a date-time} \usage{ year(x) year(x) <- value isoyear(x) epiyear(x) } \arguments{ \item{x}{a date-time object} \item{value}{a numeric object} } \value{ the years element of x as a decimal number } \description{ Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. \code{isoyear()} returns years according to the ISO 8601 week calendar. \code{epiyear()} returns years according to the epidemilogical week calendars. } \details{ year does not yet support years before 0 C.E. } \examples{ x <- ymd("2012-03-26") year(x) year(x) <- 2001 year(x) > 1995 } \references{ \url{http://en.wikipedia.org/wiki/ISO_week_date} \url{http://www.cmmcp.org/epiweek.htm} } \keyword{chron} \keyword{manip} \keyword{methods} \keyword{utilities} lubridate/man/figures/0000755000176200001440000000000013201152061014433 5ustar liggesuserslubridate/man/figures/logo.png0000644000176200001440000004075413201152061016113 0ustar liggesusersPNG  IHDRxb]esRGB pHYs  iTXtXML:com.adobe.xmp Adobe ImageReady 1 ).=?IDATx}Օym{+Cofр}Pcl`I4fSԨأ$cMb܍1l6*GQw^/|͛`fy_-S9!q*[V-.N;==^4xG2wL;^`;.; <̟-`y3=mH\ܾb\b@q :߸hv[VJs˙O<wGIu@o[ܨlOe!C 9/H.EOl{*b`fZۂ?V1}"xLGJ[yϿ+1Hwƈ] X GpX<&NA"isAzU"Xb$;.ՌIH>q  s蘃bc@jNF eo݁?R6HN Gbl 7cU>SV 'qIx~{1 6ir)gK]v API0lD4IP~vVKj&Z.;3~}:#D)S_~V1ŷYrӣ}yܺV9Q>͘yd8aRD@bD 9 RfgHaAdddhXbIfKJ\Ѥ&OGȦ鈇0bg=~Y wĴyZRO/XދHV]fD^oC#MKTH4ElVvR"Id-ϔZ1\zP8lmKʤB;ΗLT1Zcxutmm5/X2dG[( F|A7mv Fޓptڟsm+%R2~'q@f@RQYGdnK$;'[-RD,Flw9HC]TcjƹNF??sjݏ3e6ģvxh\;x@0/b։6 EJn^\c &Lʜ?CR[S+u 0{R ׄ-f4=[@)EΎ}xIY4 l85,Z3$3#שGh1)瓚Zi5@}3fOs`D$}f;{-^djƳ/6p֔Pt:naBBGٓlK %ݒ=")4ݒ=2-n\~YQ 7^k"TӢY'㾃Tp`R㎄!1WBmE"6G z z-NQ(=6*[jݧt`ړ#i4 j Tkb} ICcVUFiVk喌bk|aCC?1~n<+',%L{`TlW: L^!dʼkUR6R[[+>عy/E>n`='0{Vz3nI,;w;vGG@>4 kZyH@*͍͊͞h=mpC>n x4~hˍ ه?[0KӍg츸/9a'sss$ YY"q}|C>7b\M$: $mm GTSltfN˰ YYvVdi4%F.dRvR&XoQ6|򹩹Y32Ę9-DElɭn~a)3[szL>6c=/+Kjƃ(My1K9DK 4Rs}pdۄ1$ܒ?;b ; +pawPʄ Hvh?;nC'hJ/'7[2@dUԎ']vgaQ 5745"iL%@ 4ݏykEdAM\-V \BDLռ{Z>1P*g]Fq)gݎʶAa Ѿ݈iERnIMsh46>&^lzxoN1/jٽig1ePEΊdB+V9,cv'!`$`F@&[m"4H=B‚|6ݒEw[6r㍙H|6'xX%@EBY/̋D7ÔI3w'f3Qס89[{]Z,Ӎ:0[dqI8NGWaN 򙈦*OaewPC%[*gkϮQPκ2,Ө12J6qGpVU s *I"@cP`)Su,$)vfvk- MH >iMRܒA;rKhHqΛq +w]#ՉX`^LH$Ʉ򔕛%N 3n8a& @!H Tv)CTd%RM#.@zseG>YCno2|a(Mg%y G 5aYn< ^{| c52D_Tx=@l6nV)9:h<6TD@L.%ӳ'Hs4xDru9ׂ{eſ]{dDYw\}2=uMlbc|nƴJK qi["GZ%['x;!b̒Cu`NZG\ `0dz(QbP*CT/$WYH~ e֐SK+! 2@FP 0P$?2z(;\QDZƠ•L v~^qryqluWpT uʝW[vt*J Y*\WRU aS-Wńk|u;(@iC 4`#Bu@0ָizߞ^5FDn?PsИF!Yܒ?n !d j1 jIG1=4-Y*q֝f:2`x\H討L'"pnU  "$pU-@'']\i怄Dݐ]O9gvZw0Ast 2 Jy&P:ZdOm `6znNo4`HRiFAckt?l[GW6,<&mPٕޒr C"Z|8k@rP\D2RU ^cB~^l0vT؅ķL}3 S=H݂`)&%C6'N嚏)@j9u`OX_=Ԣ[lDη M>Kd/nu.TtI5w>jfQV Zk T%3@]A凨^/ncY=ҙA{mޙuC'1Rۥ'(,̨3V>%aЬ*.1>[s1%'O\Ƒ5ᩎ2ܴn9ݕ/x 00MIHPrhh }=xۍo JMlQG} ` J/R.:#a6uۍ7zi|r7=/RsiWf;$JHf{d53N` @1Pg^k)5˄d e|Ba< H~xuf-%˲ NjސM9/Tc,TWR@ uN> V5(ǸE۽B-g +gDz!RUYҝD tVfE\P&q(r(eZ2h_keAq2bje?sLGLHZ@u,iSNk:cs4-cHfstSM ?G.d{v(-;eeuZyz?d(Gū:P'CC59P7iON,ݲgD3 WTm`g٠>ŢE.js'ˬ@7Xv핦`d3I ";_neYԇ{W!5F=6I)7ɳoiN{J>i*YNrŒ1i9gKC4 7lYob5:$}U͹* A(>_ 0%CYiܳoGd 0.X0dQxm"TxmxX3 5JMk&])/_"y[5IJLe875B~g,OY&(OL{r_+'{FȢ}ɞ׫4"XƊRAs P2աdk^93\aD9V'L@{`9Zִ^?]O[._=]> y c"\dF3紜4KY)akΓ9k$ÚAWރ2mѢ_ڻR^i,d%KƐ2[}T!KxIihyvBKrNFx#6h(ք!3veRP%@F`EM y3$++7H%U'v^8s`ݽcdeP=A%tN7/ &>`FDUpW}*BSw;vp*Id, U+ʖ1-2CbȗD a8A3y6*pݑ&ك8p_Rq3 ^`"1΢2"{4|Np kkUӧ<>{ߪH5䩁4DM+/DkSRKV*LpEm\{хz} ה28Ivhn|FruHX oG+Vl!4!KKOe̹7>3&$V46TyzLprF2ҼɞZY =KPn>l)_'_)㤟'OީY+$Y_7ѿ?N"lrh5AHh⬣ԕ stMQ-sdw>c9nT6Vof~*{ %A3y~M(#3rJnC[ JwxG@o/j9 2y'_Y.i6yNINcO H@h gLXmd2_``eBt5(BX1o)Ki7%?|X5DGL묨>esYYEC {-pJcgf|jݮȊȪJI`g~#6=5pBf0yS=Qko(O""udp^냩"؄e͖@4sw@ǵ4 /$n<7|zz,Q]_:y"%C+%>?#ش䐚4uxvGώ2]T?vH+:+;N#?;]`vSc'OpwfYެiɓ3͒)+5/fi?Phg4b+t oT{lߗS(@[/([.l7rjpف%];{XyuT~Sy2S$U#x_XwTW8 ~J^+{/FL#lRm=Anw zreD0]-vJΩ(bП4Xu._VM \ "SӇY߉o5-Z`'~ ܱ* GO#ynKrWXUeZyIO%1g-K '}##ߜp )[XhɼU-K}::]1aٻ^.]0V)uWrz|ydG.GQM1Z]WK.~dӱrHV?z +)ˀQB2e$).ٝ UwM}4sٝX =n ̪§egp4T"aʁ`CHVo!jʝnؑźbi+HUr))JA ă/)L@^O蜝9EF|}@)<? ?_Qi#a2>%'ʯGܻЩ?~Xy{do~-S1"F;BfY7R][RJ FQ(}GΖyd{2\-1,|{U2U*:C?1 )?#֮QYxy)2{u2 _t\rxQ^31?sN*=Wr,§r2ڤu}KCuiw_]ٻ/?.`GL5~>ZϔnzV7:LuTb.64㶬E9)MQv'V~tjލrPjH|zY-t5pRJoY{@Ug6G~{1Zb 5b;zawFJf{=#w/M $>b1픓?@ou].[TRD5ȒuReJV AɆr䧟ZFf m l;S b5džE |8i [yqBD:6Lť`ZqnX J4{IWn6 '{'~\Yr j=?TՁwʭr9jޜ j5e*we !(] KΒ&y&"J.+AH/mx{YVAI[}ITɋ;A9J@6>8̟nfчYk;L6NVq7e3rK[V\ Gș[S#F_fNF N¢1e\,`Z7J5j񂽯f'BYP&ȭ;((SĠe+GN4}rpp"Kn@,gV/: %w;[4q66atהdRA@X%b3YNØ9܀:,H± ,7:ZSx{&XJ0N9˭ ^8M[p0๝S&oAr$Ykèl["cssd2."s'(& d2|ǸLdwh4(}ZhSo;&E{=!O~BQ } kgVU ֓oZ-}J_.1L#?nBٻ44sFx l9uK5Te(8+5BjSM=5PqI7PŌhCeK~qtP X΂iBp9OWoeХ. .C0B~y\A$!ܿeDks("u[Dnzdedjd=.MihAɅh7=֖rnn,QM2i&68glĹ@ِ̈́lwEӇI mZL kd/ve:{T'hsgBn,<]̣mɀt|$8} iN8_Fy:&%CvL7bS+¦dkNȰRuNpxXJxܯZW 8R/sQR ,%˂{ 9ymrٳs]&M0Ͳ.W&4OB[-lrXɭK0jdl-fi1KTCCQ0Dy L|&7³eY?H,&>Gc2g daj¼S]Wc:[y/ASAHlXs8gގ%;eWum2vA8tp1cJu ǟ@,V Bqg*㱘;]u71>K|(gBa;AF7䵧ΔCZĽ*2сՇ:u !bO !)xV7h(.s6U3G&S"/?rh{hU̹/qʚ/)L3G+]O 7e)j'r=B˥lTE nFJW _eԡ'sQcm7tL{iMȤxM|:i7)U|׌juM/7tb0 O|$jxh7H};jv˿/O\.A|sMVߝe"(D.c޴^8vH>441ic:Ea 湃׼&j8ڠ%ykLJj+U} TM#r*X,޸TaZ`?lf>AZ=\)y%tX79`N8N5RMl޲vSGpt{+A~{ѓ oveߕl?¥ԜʑK &pv7;`#QX1 *sMD5DlJp5iRt+dQ7̺X >K0"L#^h|OC΅c=5{X^h{PJ2m"9T-`sv* %l/2o|[%͇ٔtBX9smFy]c`,3܅,1ߡF?>S?G=G<h+yt{dsPLOy0glL<7="~d53f NYqTThFjm\t`sƐ5ڈvmd7m4f^vg g^7I0r6w2DQa ̌HT/SG&uf"͎J>Otx]񜱠D4@) b}x9׳Zx6@'{anj AͧyAthoa>gs}\> \|lf23s.7d퓵3wh֔,3Woԝșha 8&@0zm;4# -7=;^&{3Sȑ8B.~+ޝIFtH%'Vy^-rC9_cLBFAzmm礼6V6Y>\wc^mrD!Tx)QfZ[҈hgD,`Mꌆ"E|}mQ_Z-[&〣6o\N,fL;/u,Xog~?7-eۑ"?O(p64+gvGx$\s5M~rk ˉ3Ъ5U,]k[pl hc A"F5DCٶjP2.m'n?O] CR+6MjB] D>YKYLe>M*">\>p %囔,p |~HBE{"6yKe(ĴᅜbﴐL|pP>;L\2`&"TٴLeΕg+?hӞ&cݠ@05Gve mG/V)1&t*94|7Q}2!9T!1P¨&NѭQ@Ӟ D.I/l;7~q[l"C#|o33qnqy#=mL d "a 9*NF똠N?RoNnawa> Nܹ~—ip[YGgzmBkX![6fOXĈ㕚kH ̠̋YN`Xs@ap}`}҄Ñ!UqnhVav v-`ۑ* oVUaJE'YhQ_od8lٰOӄ )4J"Xq~7 9 s͘# yFL{ ;uFʤޢ=6#MgsnvߑYe·}ŀ '>f,_U}q4$8U ėSKr%ng{Dݏ`<yJ O9dc 6G'jL1^:GpE5{^In;lkC>:/"sB "b}]0/b ѥqgg*דrUVCp*׍|=< ,/%.ЩOw Y@<.TC?,IzSTE$#g!v@bK&hR6mϦ[Л5$e-#;J4WF+!Ҡ _4ָG^߷RV쓓i# PCn<؏apϜyQCv@e<)˽vw[/([shQ/y,A.(fCL9K=*n㴧ō{*>@QU'- 3]tKºly[԰Ir$nIvT ɴA_mu;ex`Yv`veƚ)gĉ"`C3$?8W~ʡ/ nɒyӧ"8aeIE>[岺%Fj |g"P?>-gZ<^VW~&C'5e{s%=R) rE܉/c5?_ X ;r`];6[ٞ[Rht5[n|F2p4,˰Z|fF c`V7?"Ů!8c+;,$ޣCza0IնitཱུXAp :I2*`mF-bkZ'M7͋pm~LmŘtōӈ5N4[r+l{![;+N')/'B 7xA\ 1p@ S͋Dꅻ~q?yewW6:Rd!5U͂a='>29>ڋ[ߔUM;e[C Iы1C3fDƃB _0/vXN!ռpK oՐVnI~@ C%=b",üdyrvK>kh{/bA͓nIhW=̉RJ gnR>n];wP)xhc ()30˝} D%i`Lƃ|Y/>͢R@BOq UV[)2'c;\@vF"XTۍ2fzx!Xّ[㼄+/Q뙿7xnzs`4;T=ztԎH|p>$FopFIENDB`lubridate/man/hms.Rd0000644000176200001440000000257313201152061014054 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/parse.r \name{ms} \alias{ms} \alias{hm} \alias{hms} \title{Parse periods with \strong{h}our, \strong{m}inute, and \strong{s}econd components} \usage{ ms(..., quiet = FALSE, roll = FALSE) hm(..., quiet = FALSE, roll = FALSE) hms(..., quiet = FALSE, roll = FALSE) } \arguments{ \item{...}{a character vector of hour minute second triples} \item{quiet}{logical. When TRUE function evalueates without displaying customary messages.} \item{roll}{logical. When TRUE, smaller units are rolled over to higher units if they exceed the conventional limit. For example, \code{hms("01:59:120", roll=TRUE)} produces period "2H 1M 0S".} } \value{ a vector of period objects } \description{ Transforms a character or numeric vector into a period object with the specified number of hours, minutes, and seconds. hms() recognizes all non-numeric characters except '-' as separators ('-' is used for negative durations). After hours, minutes and seconds have been parsed, the remaining input is ignored. } \examples{ ms(c("09:10", "09:02", "1:10")) ms("7 6") ms("6,5") hm(c("09:10", "09:02", "1:10")) hm("7 6") hm("6,5") x <- c("09:10:01", "09:10:02", "09:10:03") hms(x) hms("7 6 5", "3:23:::2", "2 : 23 : 33", "Finished in 9 hours, 20 min and 4 seconds") } \seealso{ \code{\link[=hm]{hm()}}, \code{\link[=ms]{ms()}} } \keyword{period} lubridate/man/reclass_date.Rd0000644000176200001440000000047513201152061015715 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/coercion.r \name{reclass_date} \alias{reclass_date} \title{Convenience method to reclass dates post-modification.} \usage{ reclass_date(new, orig) } \description{ Convenience method to reclass dates post-modification. } \keyword{internal} lubridate/man/guess_formats.Rd0000644000176200001440000000453113201152061016142 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/guess.r \name{guess_formats} \alias{guess_formats} \title{Guess possible date-times formats from a character vector} \usage{ guess_formats(x, orders, locale = Sys.getlocale("LC_TIME"), preproc_wday = TRUE, print_matches = FALSE) } \arguments{ \item{x}{input vector of date-times} \item{orders}{format orders to look for. See examples.} \item{locale}{locale to use, default to the current locale} \item{preproc_wday}{whether to preprocess week days names. Internal optimization used by ymd_hms family of functions. If TRUE, weekdays are substituted with %a or %A accordingly, so that there is no need to supply this format explicitly.} \item{print_matches}{for development purpose mainly. If TRUE prints a matrix of matched templates.} } \value{ a vector of matched formats } \description{ Guess possible date-times formats from a character vector } \examples{ x <- c('February 20th 1973', "february 14, 2004", "Sunday, May 1, 2000", "Sunday, May 1, 2000", "february 14, 04", 'Feb 20th 73', "January 5 1999 at 7pm", "jan 3 2010", "Jan 1, 1999", "jan 3 10", "01 3 2010", "1 3 10", '1 13 89', "5/27/1979", "12/31/99", "DOB:12/11/00", "-----------", 'Thu, 1 July 2004 22:30:00', 'Thu, 1st of July 2004 at 22:30:00', 'Thu, 1July 2004 at 22:30:00', 'Thu, 1July2004 22:30:00', 'Thu, 1July04 22:30:00', "21 Aug 2011, 11:15:34 pm", "-----------", "1979-05-27 05:00:59", "1979-05-27", "-----------", "3 jan 2000", "17 april 85", "27/5/1979", '20 01 89', '00/13/10', "-------", "14 12 00", "03:23:22 pm") guess_formats(x, "BdY") guess_formats(x, "Bdy") ## m also matches b and B; y also matches Y guess_formats(x, "mdy", print_matches = TRUE) ## T also matches IMSp order guess_formats(x, "T", print_matches = TRUE) ## b and B are equivalent and match, both, abreviated and full names guess_formats(x, c("mdY", "BdY", "Bdy", "bdY", "bdy"), print_matches = TRUE) guess_formats(x, c("dmy", "dbY", "dBy", "dBY"), print_matches = TRUE) guess_formats(x, c("dBY HMS", "dbY HMS", "dmyHMS", "BdY H"), print_matches = TRUE) guess_formats(x, c("ymd HMS"), print_matches = TRUE) } lubridate/man/pretty_dates.Rd0000644000176200001440000000200113201152061015756 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/pretty.r \name{pretty_dates} \alias{pretty_dates} \title{Computes attractive axis breaks for date-time data} \usage{ pretty_dates(x, n, ...) } \arguments{ \item{x}{a vector of POSIXct, POSIXlt, Date, or chron date-time objects} \item{n}{integer value of the desired number of breaks} \item{...}{additional arguments to pass to function} } \value{ a vector of date-times that can be used as axis tick marks or bin breaks } \description{ pretty.dates indentifies which unit of time the sub-intervals should be measured in to provide approximately n breaks. It then chooses a "pretty" length for the sub-intervals and sets start and endpoints that 1) span the entire range of the data, and 2) allow the breaks to occur on important date-times (i.e. on the hour, on the first of the month, etc.) } \examples{ x <- seq.Date(as.Date("2009-08-02"), by = "year", length.out = 2) pretty_dates(x, 12) } \keyword{chron} \keyword{dplot} \keyword{utilities} lubridate/man/decimal_date.Rd0000644000176200001440000000101113201152061015642 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/decimal-dates.r \name{decimal_date} \alias{decimal_date} \title{Converts a date to a decimal of its year} \usage{ decimal_date(date) } \arguments{ \item{date}{a POSIXt or Date object} } \value{ a numeric object where the date is expressed as a fraction of its year } \description{ Converts a date to a decimal of its year } \examples{ date <- ymd("2009-02-10") decimal_date(date) # 2009.11 } \keyword{chron} \keyword{manip} \keyword{methods} lubridate/man/origin.Rd0000644000176200001440000000075513201152061014554 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/instants.r \docType{data} \name{origin} \alias{origin} \title{1970-01-01 UTC} \format{An object of class \code{POSIXct} (inherits from \code{POSIXt}) of length 1.} \usage{ origin } \description{ Origin is the date-time for 1970-01-01 UTC in POSIXct format. This date-time is the origin for the numbering system used by POSIXct, POSIXlt, chron, and Date classes. } \examples{ origin } \keyword{chron} \keyword{data} lubridate/man/round_date.Rd0000644000176200001440000001300313201152061015377 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/round.r \name{round_date} \alias{round_date} \alias{floor_date} \alias{ceiling_date} \title{Round, floor and ceiling methods for date-time objects} \usage{ round_date(x, unit = "second", week_start = getOption("lubridate.week.start", 7)) floor_date(x, unit = "seconds", week_start = getOption("lubridate.week.start", 7)) ceiling_date(x, unit = "seconds", change_on_boundary = NULL, week_start = getOption("lubridate.week.start", 7)) } \arguments{ \item{x}{a vector of date-time objects} \item{unit}{a character string specifying a time unit or a multiple of a unit to be rounded to. Valid base units are \code{second}, \code{minute}, \code{hour}, \code{day}, \code{week}, \code{month}, \code{bimonth}, \code{quarter}, \code{season}, \code{halfyear} and \code{year}. Arbitrary unique English abbreviations as in the \code{\link[=period]{period()}} constructor are allowed. Rounding to multiple of units (except weeks) is supported.} \item{week_start}{when unit is \code{weeks} specify the reference day; 7 being Sunday.} \item{change_on_boundary}{If NULL (the default) don't change instants on the boundary (\code{ceiling_date(ymd_hms('2000-01-01 00:00:00'))} is \code{2000-01-01 00:00:00}), but round up \code{Date} objects to the next boundary (\code{ceiling_date(ymd("2000-01-01"), "month")} is \code{"2000-02-01"}). When \code{TRUE}, instants on the boundary are rounded up to the next boundary. When \code{FALSE}, date-time on the boundary are never rounded up (this was the default for \pkg{lubridate} prior to \code{v1.6.0}. See section \code{Rounding Up Date Objects} below for more details.} } \description{ Rounding to the nearest unit or multiple of a unit are supported. All meaningfull specifications in English language are supported - secs, min, mins, 2 minutes, 3 years etc. Rounding to fractional seconds is supported. Please note that rounding to fractions smaller than 1s can lead to large precision errors due to the floating point representation of the POSIXct objects. See examples. \code{round_date()} takes a date-time object and rounds it to the nearest value of the specified time unit. For rounding date-times which is exactly halfway between two consecutive units, the convention is to round up. Note that this is in line with the behavior of R's \code{\link[base:round.POSIXt]{base::round.POSIXt()}} function but does not follow the convention of the base \code{\link[base:round]{base::round()}} function which "rounds to the even digit" per IEC 60559. \code{floor_date()} takes a date-time object and rounds it down to the nearest boundary of the specified time unit. \code{ceiling_date()} takes a date-time object and rounds it up to the nearest boundary of the specified time unit. } \details{ In \pkg{lubridate}, rounding of a date-time objects tries to preserve the class of the input object whenever possible. This is done by first rounding to an instant and then converting to the original class by usual R conventions. } \section{Rounding Up Date Objects}{ By default rounding up \code{Date} objects follows 3 steps: \enumerate{ \item Convert to an instant representing lower bound of the Date: \code{2000-01-01} --> \code{2000-01-01 00:00:00} \item Round up to the \strong{next} closest rounding unit boundary. For example, if the rounding unit is \code{month} then next closest boundary of \code{2000-01-01} is \code{2000-02-01 00:00:00}. The motivation for this is that the "partial" \code{2000-01-01} is conceptually an interval (\code{2000-01-01 00:00:00} -- \code{2000-01-02 00:00:00}) and the day hasn't started clocking yet at the exact boundary \code{00:00:00}. Thus, it seems wrong to round up a day to its lower boundary. The behavior on the boundary can be changed by setting \code{change_on_boundary} to a non-\code{NULL} value. \item If rounding unit is smaller than a day, return the instant from step 2 (\code{POSIXct}), otherwise convert to and return a \code{Date} object. } } \examples{ ## print fractional seconds options(digits.secs=6) x <- ymd_hms("2009-08-03 12:01:59.23") round_date(x, ".5s") round_date(x, "sec") round_date(x, "second") round_date(x, "minute") round_date(x, "5 mins") round_date(x, "hour") round_date(x, "2 hours") round_date(x, "day") round_date(x, "week") round_date(x, "month") round_date(x, "bimonth") round_date(x, "quarter") == round_date(x, "3 months") round_date(x, "halfyear") round_date(x, "year") x <- ymd_hms("2009-08-03 12:01:59.23") floor_date(x, ".1s") floor_date(x, "second") floor_date(x, "minute") floor_date(x, "hour") floor_date(x, "day") floor_date(x, "week") floor_date(x, "month") floor_date(x, "bimonth") floor_date(x, "quarter") floor_date(x, "season") floor_date(x, "halfyear") floor_date(x, "year") x <- ymd_hms("2009-08-03 12:01:59.23") ceiling_date(x, ".1 sec") # imprecise representation at 0.1 sec !!! ceiling_date(x, "second") ceiling_date(x, "minute") ceiling_date(x, "5 mins") ceiling_date(x, "hour") ceiling_date(x, "day") ceiling_date(x, "week") ceiling_date(x, "month") ceiling_date(x, "bimonth") == ceiling_date(x, "2 months") ceiling_date(x, "quarter") ceiling_date(x, "season") ceiling_date(x, "halfyear") ceiling_date(x, "year") ## As of R 3.4.2 POSIXct printing of fractional numbers is wrong as.POSIXct("2009-08-03 12:01:59.3") ## -> "2009-08-03 12:01:59.2 CEST" ceiling_date(x, ".1 sec") ## -> "2009-08-03 12:01:59.2 CEST" x <- ymd("2000-01-01") ceiling_date(x, "month") ceiling_date(x, "month", change_on_boundary = TRUE) } \seealso{ \code{\link[base:round]{base::round()}} } \keyword{chron} \keyword{manip} lubridate/man/stamp.Rd0000644000176200001440000000564213234630403014420 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/stamp.r \name{stamp} \alias{stamp} \alias{stamp_date} \alias{stamp_time} \title{Format dates and times based on human-friendly templates} \usage{ stamp(x, orders = lubridate_formats, locale = Sys.getlocale("LC_TIME"), quiet = FALSE) stamp_date(x, locale = Sys.getlocale("LC_TIME")) stamp_time(x, locale = Sys.getlocale("LC_TIME")) } \arguments{ \item{x}{a character vector of templates.} \item{orders}{orders are sequences of formatting characters which might be used for disambiguation. For example "ymd hms", "aym" etc. See \code{\link[=guess_formats]{guess_formats()}} for a list of available formats.} \item{locale}{locale in which \code{x} is encoded. On Linux-like systems use \code{locale -a} in the terminal to list available locales.} \item{quiet}{whether to output informative messages.} } \value{ a function to be applied on a vector of dates } \description{ Stamps are just like \code{\link[=format]{format()}}, but based on human-frendly templates like "Recorded at 10 am, September 2002" or "Meeting, Sunday May 1, 2000, at 10:20 pm". } \details{ \code{stamp()} is a stamping function date-time templates mainly, though it correctly handles all date and time formats as long as they are unambiguous. \code{stamp_date()}, and \code{stamp_time()} are the specialized stamps for dates and times (MHS). These function might be useful when the input template is unambiguous and matches both a time and a date format. Lubridate tries it's best to figure our the formats, but often a given format can be interpreted in several ways. One way to deal with the situation is to provide unambiguous formats like 22/05/81 instead of 10/05/81 if you want d/m/y format. Another option is to use a more specialized stamp_date and stamp_time. The core function \code{stamp()} give priority to longer date-time formats. Another option is to provide a vector of several values as \code{x} parameter. Then \pkg{lubridate} will choose the format which fits \code{x} the best. Note that longer formats are preferred. If you have "22:23:00 PM" then "HMSp" format will be given priority to shorter "HMS" order which also fits the supplied string. Finally, you can give desired format order directly as \code{orders} argument. } \examples{ D <- ymd("2010-04-05") - days(1:5) stamp("March 1, 1999")(D) sf <- stamp("Created on Sunday, Jan 1, 1999 3:34 pm") sf(D) stamp("Jan 01")(D) stamp("Sunday, May 1, 2000", locale = "C")(D) stamp("Sun Aug 5")(D) #=> "Sun Aug 04" "Sat Aug 04" "Fri Aug 04" "Thu Aug 04" "Wed Aug 03" stamp("12/31/99")(D) #=> "06/09/11" stamp("Sunday, May 1, 2000 22:10", locale = "C")(D) stamp("2013-01-01T06:00:00Z")(D) stamp("2013-01-01T00:00:00-06")(D) stamp("2013-01-01T00:00:00-08:00")(force_tz(D, "America/Chicago")) } \seealso{ \code{\link[=guess_formats]{guess_formats()}}, \code{\link[=parse_date_time]{parse_date_time()}}, \code{\link[=strptime]{strptime()}} } lubridate/man/Timespan-class.Rd0000644000176200001440000000072113201152061016141 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/timespans.r \docType{class} \name{Timespan-class} \alias{Timespan-class} \alias{*,Timespan,Timespan-method} \alias{\%/\%,Timespan,Timespan-method} \alias{\%/\%,difftime,Timespan-method} \title{Timespan class} \description{ Timespan is an S4 class with no slots. It is extended by the \linkS4class{Interval}, \linkS4class{Period}, and \linkS4class{Duration} classes. } \keyword{internal} lubridate/man/as.period.Rd0000644000176200001440000000677213263111216015163 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/coercion.r \name{as.period} \alias{as.period} \alias{as.period,numeric-method} \alias{as.period,difftime-method} \alias{as.period,Interval-method} \alias{as.period,Duration-method} \alias{as.period,Period-method} \alias{as.period,logical-method} \alias{as.period,character-method} \title{Change an object to a period} \usage{ as.period(x, unit, ...) } \arguments{ \item{x}{an interval, difftime, or numeric object} \item{unit}{A character string that specifies which time units to build period in. unit is only implemented for the as.period.numeric method and the as.period.interval method. For as.period.interval, as.period will convert intervals to units no larger than the specified unit.} \item{...}{additional arguments to pass to as.period} } \value{ a period object } \description{ as.period changes Interval, Duration, difftime and numeric class objects to Period class objects with the specified units. } \details{ Users must specify which time units to measure the period in. The exact length of each time unit in a period will depend on when it occurs. See \linkS4class{Period} and \code{\link[=period]{period()}}. The choice of units is not trivial; units that are normally equal may differ in length depending on when the time period occurs. For example, when a leap second occurs one minute is longer than 60 seconds. Because periods do not have a fixed length, they can not be accurately converted to and from Duration objects. Duration objects measure time spans in exact numbers of seconds, see \linkS4class{Duration}. Hence, a one to one mapping does not exist between durations and periods. When used with a Duration object, as.period provides an inexact estimate; the duration is broken into time units based on the most common lengths of time units, in seconds. Because the length of months are particularly variable, a period with a months unit can not be coerced from a duration object. For an exact transformation, first transform the duration to an interval with \code{\link[=as.interval]{as.interval()}}. Coercing an interval to a period may cause surprising behavior if you request periods with small units. A leap year is 366 days long, but one year long. Such an interval will convert to 366 days when unit is set to days and 1 year when unit is set to years. Adding 366 days to a date will often give a different result than adding one year. Daylight savings is the one exception where this does not apply. Interval lengths are calculated on the UTC timeline, which does not use daylight savings. Hence, periods converted with seconds or minutes will not reflect the actual variation in seconds and minutes that occurs due to daylight savings. These periods will show the "naive" change in seconds and minutes that is suggested by the differences in clock time. See the examples below. } \examples{ span <- interval(ymd_hms("2009-01-01 00:00:00"), ymd_hms("2010-02-02 01:01:01")) #interval as.period(span) as.period(span, unit = "day") "397d 1H 1M 1S" leap <- interval(ymd("2016-01-01"), ymd("2017-01-01")) as.period(leap, unit = "days") as.period(leap, unit = "years") dst <- interval(ymd("2016-11-06", tz = "America/Chicago"), ymd("2016-11-07", tz = "America/Chicago")) # as.period(dst, unit = "seconds") as.period(dst, unit = "hours") per <- period(hours = 10, minutes = 6) as.numeric(per, "hours") as.numeric(per, "minutes") } \seealso{ \linkS4class{Period}, \code{\link[=period]{period()}} } \keyword{chron} \keyword{classes} \keyword{manip} \keyword{methods} lubridate/man/ymd_hms.Rd0000644000176200001440000001316313263116135014734 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/parse.r \name{ymd_hms} \alias{ymd_hms} \alias{ymd_hm} \alias{ymd_h} \alias{dmy_hms} \alias{dmy_hm} \alias{dmy_h} \alias{mdy_hms} \alias{mdy_hm} \alias{mdy_h} \alias{ydm_hms} \alias{ydm_hm} \alias{ydm_h} \title{Parse date-times with \strong{y}ear, \strong{m}onth, and \strong{d}ay, \strong{h}our, \strong{m}inute, and \strong{s}econd components.} \usage{ ymd_hms(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) ymd_hm(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) ymd_h(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) dmy_hms(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) dmy_hm(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) dmy_h(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) mdy_hms(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) mdy_hm(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) mdy_h(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) ydm_hms(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) ydm_hm(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) ydm_h(..., quiet = FALSE, tz = "UTC", locale = Sys.getlocale("LC_TIME"), truncated = 0) } \arguments{ \item{...}{a character vector of dates in year, month, day, hour, minute, second format} \item{quiet}{logical. When TRUE function evalueates without displaying customary messages.} \item{tz}{a character string that specifies which time zone to parse the date with. The string must be a time zone that is recognized by the user's OS.} \item{locale}{locale to be used, see \link{locales}. On linux systems you can use \code{system("locale -a")} to list all the installed locales.} \item{truncated}{integer, indicating how many formats can be missing. See details.} } \value{ a vector of \link{POSIXct} date-time objects } \description{ Transform dates stored as character or numeric vectors to POSIXct objects. ymd_hms family of functions recognize all non-alphanumeric separators (with the exception of "." if \code{frac = TRUE}) and correctly handle heterogeneous date-time representations. For more flexibility in treatment of heterogeneous formats, see low level parser \code{\link[=parse_date_time]{parse_date_time()}}. } \details{ ymd_hms() functions automatically assigns the Universal Coordinated Time Zone (UTC) to the parsed date. This time zone can be changed with \code{\link[=force_tz]{force_tz()}}. The most common type of irregularity in date-time data is the truncation due to rounding or unavailability of the time stamp. If the \code{truncated} parameter is non-zero, the \code{ymd_hms} functions also check for truncated formats. For example, \code{ymd_hms()} with \code{truncated = 3} will also parse incomplete dates like \code{2012-06-01 12:23}, \code{2012-06-01 12} and \code{2012-06-01}. NOTE: The \code{ymd} family of functions are based on \code{\link[=strptime]{strptime()}} which currently fails to parse \code{\%y-\%m} formats. In case of heterogeneous date formats \code{ymd_hms()} family guesses formats based on a sub-set of the input vector. If the input vector contains many missing values or non-date strings, the sub-set might not contain meaningful dates and the date-time format won't be guessed resulting in "All formats failed to parse" error. In such cases please see \code{\link[=parse_date_time]{parse_date_time()}} for a more flexible parsing interface. As of version 1.3.0, \pkg{lubridate}'s parse functions no longer return a message that displays which format they used to parse their input. You can change this by setting the \code{lubridate.verbose} option to \code{TRUE} with \code{options(lubridate.verbose = TRUE)}. } \examples{ x <- c("2010-04-14-04-35-59", "2010-04-01-12-00-00") ymd_hms(x) x <- c("2011-12-31 12:59:59", "2010-01-01 12:00:00") ymd_hms(x) ## ** heterogenuous formats ** x <- c(20100101120101, "2009-01-02 12-01-02", "2009.01.03 12:01:03", "2009-1-4 12-1-4", "2009-1, 5 12:1, 5", "200901-08 1201-08", "2009 arbitrary 1 non-decimal 6 chars 12 in between 1 !!! 6", "OR collapsed formats: 20090107 120107 (as long as prefixed with zeros)", "Automatic wday, Thu, detection, 10-01-10 10:01:10 and p format: AM", "Created on 10-01-11 at 10:01:11 PM") ymd_hms(x) ## ** fractional seconds ** op <- options(digits.secs=3) dmy_hms("20/2/06 11:16:16.683") options(op) ## ** different formats for ISO8601 timezone offset ** ymd_hms(c("2013-01-24 19:39:07.880-0600", "2013-01-24 19:39:07.880", "2013-01-24 19:39:07.880-06:00", "2013-01-24 19:39:07.880-06", "2013-01-24 19:39:07.880Z")) ## ** internationalization ** \dontrun{ x_RO <- "Ma 2012 august 14 11:28:30 " ymd_hms(x_RO, locale = "ro_RO.utf8") } ## ** truncated time-dates ** x <- c("2011-12-31 12:59:59", "2010-01-01 12:11", "2010-01-01 12", "2010-01-01") ymd_hms(x, truncated = 3) x <- c("2011-12-31 12:59", "2010-01-01 12", "2010-01-01") ymd_hm(x, truncated = 2) ## ** What lubridate might not handle ** ## Extremely weird cases when one of the separators is "" and some of the ## formats are not in double digits might not be parsed correctly: \dontrun{ ymd_hm("20100201 07-01", "20100201 07-1", "20100201 7-01")} } \seealso{ \itemize{ \item \code{\link[=ymd]{ymd()}}, \code{\link[=hms]{hms()}} \item \code{\link[=parse_date_time]{parse_date_time()}} for the underlying mechanism } } \keyword{POSIXt} \keyword{parse} lubridate/man/hidden_aliases.Rd0000644000176200001440000002020713234630403016222 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/intervals.r, R/durations.r, R/periods.r, % R/hidden.r \docType{data} \name{hidden_aliases} \alias{hidden_aliases} \alias{Arith,Interval,ANY-method} \alias{Arith,ANY,Interval-method} \alias{intersect,Interval,Interval-method} \alias{union,Interval,Interval-method} \alias{setdiff,Interval,Interval-method} \alias{as.numeric,Interval-method} \alias{show,Interval-method} \alias{c,Interval-method} \alias{rep,Interval-method} \alias{[,Interval-method} \alias{[<-,Interval,ANY,ANY,ANY-method} \alias{[[,Interval-method} \alias{[[<-,Interval,ANY,ANY,ANY-method} \alias{$,Interval-method} \alias{$<-,Interval-method} \alias{as.difftime,Interval-method} \alias{as.character,Interval-method} \alias{+,Interval,Duration-method} \alias{+,Interval,Interval-method} \alias{+,Interval,Period-method} \alias{+,Interval,Date-method} \alias{+,Date,Interval-method} \alias{+,Interval,difftime-method} \alias{+,difftime,Interval-method} \alias{+,Interval,numeric-method} \alias{+,numeric,Interval-method} \alias{+,Interval,POSIXct-method} \alias{+,POSIXct,Interval-method} \alias{+,Interval,POSIXlt-method} \alias{+,POSIXlt,Interval-method} \alias{/,Interval,Duration-method} \alias{/,Interval,Interval-method} \alias{/,Interval,Period-method} \alias{/,Interval,difftime-method} \alias{/,difftime,Interval-method} \alias{/,Interval,numeric-method} \alias{/,numeric,Interval-method} \alias{*,Interval,ANY-method} \alias{*,ANY,Interval-method} \alias{-,Interval,missing-method} \alias{-,Interval,Interval-method} \alias{-,Date,Interval-method} \alias{-,POSIXct,Interval-method} \alias{-,POSIXlt,Interval-method} \alias{-,numeric,Interval-method} \alias{-,Interval,Date-method} \alias{-,Interval,POSIXct-method} \alias{-,Interval,POSIXlt-method} \alias{-,Interval,numeric-method} \alias{-,Duration,Interval-method} \alias{-,Period,Interval-method} \alias{\%\%,Interval,Duration-method} \alias{\%\%,Interval,Interval-method} \alias{\%\%,Interval,Period-method} \alias{\%\%,Interval,Duration} \alias{\%\%,Interval,Interval} \alias{\%\%,Interval,Period} \alias{-,Date,Interval} \alias{-,Duration,Interval} \alias{-,Interval,Date} \alias{-,Interval,Interval} \alias{-,Interval,POSIXct} \alias{-,Interval,POSIXlt} \alias{-,Interval,numeric} \alias{-,POSIXct,Interval} \alias{-,POSIXlt,Interval} \alias{-,numeric,Interval} \alias{hidden_aliases} \alias{Compare,Duration,ANY-method} \alias{Compare,Duration,Duration-method} \alias{Compare,difftime,Duration-method} \alias{Compare,ANY,Duration-method} \alias{Compare,Duration,Period-method} \alias{Compare,Duration,difftime-method} \alias{Compare,character,Duration-method} \alias{Compare,Duration,character-method} \alias{as.numeric,Duration-method} \alias{show,Duration-method} \alias{c,Duration-method} \alias{rep,Duration-method} \alias{[,Duration-method} \alias{[<-,Duration,ANY,ANY,ANY-method} \alias{[[,Duration-method} \alias{[[<-,Duration,ANY,ANY,ANY-method} \alias{$,Duration-method} \alias{$<-,Duration-method} \alias{as.difftime,Duration-method} \alias{as.character,Duration-method} \alias{+,Duration,Duration-method} \alias{+,Duration,Interval-method} \alias{+,Duration,Period-method} \alias{+,Duration,Date-method} \alias{+,Date,Duration-method} \alias{+,Duration,difftime-method} \alias{+,difftime,Duration-method} \alias{+,Duration,numeric-method} \alias{+,numeric,Duration-method} \alias{+,Duration,POSIXct-method} \alias{+,POSIXct,Duration-method} \alias{+,Duration,POSIXlt-method} \alias{+,POSIXlt,Duration-method} \alias{-,Duration,ANY-method} \alias{/,Duration,Duration-method} \alias{/,Duration,Interval-method} \alias{/,Duration,Period-method} \alias{/,Duration,difftime-method} \alias{/,difftime,Duration-method} \alias{/,Duration,numeric-method} \alias{/,numeric,Duration-method} \alias{*,Duration,ANY-method} \alias{*,ANY,Duration-method} \alias{\%\%,Duration,Duration-method} \alias{\%\%,Duration,Interval-method} \alias{\%\%,Duration,Period-method} \alias{-,Duration,missing-method} \alias{-,ANY,Duration-method} \alias{hidden_aliases} \alias{Arith,ANY,Period-method} \alias{Arith,Duration,Period-method} \alias{Arith,Period,Duration-method} \alias{Compare,Period,Duration-method} \alias{Compare,numeric,Period-method} \alias{Compare,difftime,Period-method} \alias{Compare,Period,difftime-method} \alias{Compare,Period,Period-method} \alias{Compare,Period,character-method} \alias{Compare,Period,numeric-method} \alias{Compare,character,Period-method} \alias{second,Period-method} \alias{second<-,Period-method} \alias{minute,Period-method} \alias{minute<-,Period-method} \alias{hour,Period-method} \alias{hour<-,Period-method} \alias{Arith,Period,ANY-method} \alias{day,Period-method} \alias{day<-,Period-method} \alias{month,Period-method} \alias{month<-,Period-method} \alias{year,Period-method} \alias{year<-,Period-method} \alias{date,Period-method} \alias{date<-,Period-method} \alias{as.numeric,Period-method} \alias{show,Period-method} \alias{c,Period-method} \alias{rep,Period-method} \alias{[,Period-method} \alias{[<-,Period,ANY,ANY,Period-method} \alias{[[,Period-method} \alias{[[<-,Period,ANY,ANY,Period-method} \alias{$,Period-method} \alias{$<-,Period-method} \alias{as.difftime,Period-method} \alias{as.character,Period-method} \alias{+,Period,Duration-method} \alias{+,Period,Interval-method} \alias{+,Period,Period-method} \alias{+,Period,Date-method} \alias{+,Date,Period-method} \alias{+,Period,difftime-method} \alias{+,difftime,Period-method} \alias{+,Period,numeric-method} \alias{+,numeric,Period-method} \alias{+,Period,POSIXct-method} \alias{+,POSIXct,Period-method} \alias{+,Period,POSIXlt-method} \alias{+,POSIXlt,Period-method} \alias{/,Period,Duration-method} \alias{/,Period,Interval-method} \alias{/,Period,Period-method} \alias{/,Period,difftime-method} \alias{/,difftime,Period-method} \alias{/,Period,numeric-method} \alias{/,numeric,Period-method} \alias{*,Period,ANY-method} \alias{*,ANY,Period-method} \alias{-,Period,ANY-method} \alias{-,Period,missing-method} \alias{-,ANY,Period-method} \alias{\%\%,Period,Duration-method} \alias{\%\%,Period,Interval-method} \alias{\%\%,Period,Period-method} \alias{>,Period,Period-method} \alias{>=,Period,Period-method} \alias{==,Period,Period-method} \alias{!=,Period,Period-method} \alias{<=,Period,Period-method} \alias{<,Period,Period-method} \alias{>,Period,Duration-method} \alias{>=,Period,Duration-method} \alias{==,Period,Duration-method} \alias{!=,Period,Duration-method} \alias{<=,Period,Duration-method} \alias{<,Period,Duration-method} \alias{>,Duration,Period-method} \alias{>=,Duration,Period-method} \alias{==,Duration,Period-method} \alias{!=,Duration,Period-method} \alias{<=,Duration,Period-method} \alias{<,Duration,Period-method} \alias{>,Period,numeric-method} \alias{>=,Period,numeric-method} \alias{==,Period,numeric-method} \alias{!=,Period,numeric-method} \alias{<=,Period,numeric-method} \alias{<,Period,numeric-method} \alias{>,numeric,Period-method} \alias{>=,numeric,Period-method} \alias{==,numeric,Period-method} \alias{!=,numeric,Period-method} \alias{<=,numeric,Period-method} \alias{<,numeric,Period-method} \alias{!=,Duration,Period} \alias{!=,Period,Duration} \alias{!=,Period,Period} \alias{!=,Period,numeric} \alias{!=,numeric,Period} \alias{\%\%,Period,Duration} \alias{\%\%,Period,Interval} \alias{\%\%,Period,Period} \alias{*,ANY,Period} \alias{*,Period,ANY} \alias{-,ANY,Period} \alias{-,Period,Interval} \alias{-,Period,missing} \alias{/,numeric,Period} \alias{<,Duration,Period} \alias{<,Period,Duration} \alias{<,Period,Period} \alias{<,Period,numeric} \alias{<,numeric,Period} \alias{<=,Duration,Period} \alias{<=,Period,Duration} \alias{<=,Period,Period} \alias{<=,Period,numeric} \alias{<=,numeric,Period} \alias{==,Duration,Period} \alias{==,Period,Duration} \alias{==,Period,Period} \alias{==,Period,numeric} \alias{==,numeric,Period} \alias{>,Duration,Period} \alias{>,Period,Duration} \alias{>,Period,Period} \alias{>,Period,numeric} \alias{>,numeric,Period} \alias{>=,Duration,Period} \alias{>=,Period,Duration} \alias{>=,Period,Period} \alias{>=,Period,numeric} \alias{>=,numeric,Period} \alias{hidden_aliases} \title{Internal page for hidden aliases} \description{ For S4 methods that require a documentation entry but only clutter the index. } \keyword{internal} lubridate/man/quarter.Rd0000644000176200001440000000174013201152061014743 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-quarter.r \name{quarter} \alias{quarter} \alias{semester} \title{Get the fiscal quarter and semester of a date-time} \usage{ quarter(x, with_year = FALSE, fiscal_start = 1) semester(x, with_year = FALSE) } \arguments{ \item{x}{a date-time object of class POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, fts or anything else that can be converted with as.POSIXlt} \item{with_year}{logical indicating whether or not to include the quarter's year.} \item{fiscal_start}{numeric indicating the starting month of a fiscal year} } \value{ numeric } \description{ Quarters divide the year into fourths. Semesters divide the year into halfs. } \examples{ x <- ymd(c("2012-03-26", "2012-05-04", "2012-09-23", "2012-12-31")) quarter(x) quarter(x, with_year = TRUE) quarter(x, with_year = TRUE, fiscal_start = 11) semester(x) semester(x, with_year = TRUE) } lubridate/man/second.Rd0000644000176200001440000000127413201152061014535 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-second.r \name{second} \alias{second} \alias{second<-} \title{Get/set seconds component of a date-time} \usage{ second(x) second(x) <- value } \arguments{ \item{x}{a date-time object} \item{value}{numeric value to be assigned} } \value{ the seconds element of x as a decimal number } \description{ Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. } \examples{ x <- ymd("2012-03-26") second(x) second(x) <- 1 second(x) <- 61 second(x) > 2 } \keyword{chron} \keyword{manip} \keyword{methods} \keyword{utilities} lubridate/man/is.POSIXt.Rd0000644000176200001440000000123513201152061014757 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/POSIXt.r \name{is.POSIXt} \alias{is.POSIXt} \alias{is.POSIXlt} \alias{is.POSIXct} \title{Is x a POSIXct or POSIXlt object?} \usage{ is.POSIXt(x) is.POSIXlt(x) is.POSIXct(x) } \arguments{ \item{x}{an R object} } \value{ TRUE if x is a POSIXct or POSIXlt object, FALSE otherwise. } \description{ Is x a POSIXct or POSIXlt object? } \examples{ is.POSIXt(as.Date("2009-08-03")) # FALSE is.POSIXt(as.POSIXct("2009-08-03")) # TRUE } \seealso{ \code{\link[=is.instant]{is.instant()}}, \code{\link[=is.timespan]{is.timespan()}}, \code{\link[=is.Date]{is.Date()}} } \keyword{chron} \keyword{logic} lubridate/man/lakers.Rd0000644000176200001440000000131513201152061014537 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/data.r \docType{data} \name{lakers} \alias{lakers} \title{Lakers 2008-2009 basketball data set} \description{ This data set contains play by play statistics of each Los Angeles Lakers basketball game in the 2008-2009 season. Data includes the date, opponent, and type of each game (home or away). Each play is described by the time on the game clock when the play was made, the period in which the play was attempted, the type of play, the player and team who made the play, the result of the play, and the location on the court where each play was made. } \references{ Originally taken from www.basketballgeek.com/data/. } \keyword{data} lubridate/man/days_in_month.Rd0000644000176200001440000000100313201152061016103 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-month.r \name{days_in_month} \alias{days_in_month} \title{Get the number of days in the month of a date-time} \usage{ days_in_month(x) } \arguments{ \item{x}{a date-time object} } \value{ An integer of the number of days in the month component of the date-time object. } \description{ Date-time must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. } lubridate/man/Deprecated.Rd0000644000176200001440000000220513201152061015315 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/deprecated.r \name{Deprecated-lubridate} \alias{Deprecated-lubridate} \alias{new_period} \alias{new_interval} \alias{new_duration} \alias{new_difftime} \alias{eseconds} \alias{eminutes} \alias{ehours} \alias{edays} \alias{eweeks} \alias{eyears} \alias{emilliseconds} \alias{emicroseconds} \alias{enanoseconds} \alias{epicoseconds} \alias{here} \alias{olson_time_zones} \title{Deprecated functions in the lubridate package} \usage{ new_period(...) new_interval(...) new_duration(...) new_difftime(...) eseconds(x = 1) eminutes(x = 1) ehours(x = 1) edays(x = 1) eweeks(x = 1) eyears(x = 1) emilliseconds(x = 1) emicroseconds(x = 1) enanoseconds(x = 1) epicoseconds(x = 1) here() olson_time_zones(order_by = c("name", "longitude")) } \arguments{ \item{...}{arguments to be passed to the functions (obscured to enforce the usage of new functions)} \item{x}{numeric value to be converted into duration} \item{order_by}{Return names alphabetically (the default) or from West to East.} } \description{ Deprecated functions in the lubridate package } \keyword{internal} lubridate/man/is.timespan.Rd0000644000176200001440000000127313201152061015513 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/timespans.r \name{is.timespan} \alias{is.timespan} \title{Is x a length of time?} \usage{ is.timespan(x) } \arguments{ \item{x}{an R object} } \value{ TRUE if x is a period, interval, duration, or difftime object, FALSE otherwise. } \description{ Is x a length of time? } \examples{ is.timespan(as.Date("2009-08-03")) # FALSE is.timespan(duration(second = 1)) # TRUE } \seealso{ \code{\link[=is.instant]{is.instant()}}, \code{\link[=is.duration]{is.duration()}}, \code{\link[=is.difftime]{is.difftime()}}, \code{\link[=is.period]{is.period()}}, \code{\link[=is.interval]{is.interval()}} } \keyword{chron} \keyword{logic} lubridate/man/make_difftime.Rd0000644000176200001440000000437713201152061016055 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/difftimes.r \name{make_difftime} \alias{make_difftime} \title{Create a difftime object.} \usage{ make_difftime(num = NULL, units = "auto", ...) } \arguments{ \item{num}{Optional number of seconds} \item{units}{a character vector that lists the type of units to use for the display of the return value (see examples). If \code{units} is "auto" (the default) the display units are computed automatically. This might create undesirable effects when converting \code{difftime} objects to numeric values in data processing.} \item{...}{a list of time units to be included in the difftime and their amounts. Seconds, minutes, hours, days, and weeks are supported. Normally only one of \code{num} or \code{...} are present. If both are present, the \code{difftime} objects are concatenated.} } \value{ a difftime object } \description{ \code{make_difftime()} creates a difftime object with the specified number of units. Entries for different units are cumulative. difftime displays durations in various units, but these units are estimates given for convenience. The underlying object is always recorded as a fixed number of seconds. } \details{ Conceptually, difftime objects are a type of duration. They measure the exact passage of time but do not always align with measurements made in larger units of time such as hours, months and years. This is because the length of larger time units can be affected by conventions such as leap years and Daylight Savings Time. \pkg{lubridate} provides a second class for measuring durations, the Duration class. } \examples{ make_difftime(1) make_difftime(60) make_difftime(3600) make_difftime(3600, units = "minute") # Time difference of 60 mins make_difftime(second = 90) # Time difference of 1.5 mins make_difftime(minute = 1.5) # Time difference of 1.5 mins make_difftime(second = 3, minute = 1.5, hour = 2, day = 6, week = 1) # Time difference of 13.08441 days make_difftime(hour = 1, minute = -60) # Time difference of 0 secs make_difftime(day = -1) # Time difference of -1 days make_difftime(120, day = -1, units = "minute") # Time differences in mins } \seealso{ \code{\link[=duration]{duration()}}, \code{\link[=as.duration]{as.duration()}} } \keyword{chron} \keyword{classes} lubridate/man/interval.Rd0000644000176200001440000001500313234630403015110 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/intervals.r \name{interval} \alias{interval} \alias{\%--\%} \alias{is.interval} \alias{int_start} \alias{int_start<-} \alias{int_end} \alias{int_end<-} \alias{int_length} \alias{int_flip} \alias{int_shift} \alias{int_overlaps} \alias{int_standardize} \alias{int_aligns} \alias{int_diff} \title{Utilities for creation and manipulation of \code{Interval} objects} \usage{ interval(start, end = NULL, tzone = tz(start)) start \%--\% end is.interval(x) int_start(int) int_start(int) <- value int_end(int) int_end(int) <- value int_length(int) int_flip(int) int_shift(int, by) int_overlaps(int1, int2) int_standardize(int) int_aligns(int1, int2) int_diff(times) } \arguments{ \item{start, end}{POSIXt, Date or a character vectors. When \code{start} is a character vector and end is \code{NULL}, ISO 8601 specification is assumed but with much more permisive lubridate style parsing both for dates and periods (see examples).} \item{tzone}{a recognized timezone to display the interval in} \item{x}{an R object} \item{int}{an interval object} \item{value}{interval's start/end to be assigned to \code{int}} \item{by}{A period or duration object to shift by (for \code{int_shift})} \item{int1}{an Interval object (for \code{int_overlaps()}, \code{int_aligns()})} \item{int2}{an Interval object (for \code{int_overlaps()}, \code{int_aligns()})} \item{times}{A vector of POSIXct, POSIXlt or Date class date-times (for \code{int_diff()})} } \value{ \code{interval()} -- \linkS4class{Interval} object. \code{int_start()} and \code{int_end()} return a POSIXct date object when used as an accessor. Nothing when used as a setter. \code{int_length()} -- numeric length of the interval in seconds. A negative number connotes a negative interval. \code{int_flip()} -- flipped interval object \code{int_shift()} -- an Interval object \code{int_overlaps()} -- logical, TRUE if int1 and int2 overlap by at least one second. FALSE otherwise \code{int_aligns()} -- logical, TRUE if int1 and int2 begin or end on the same moment. FALSE otherwise \code{int_diff()} -- interval object that contains the n-1 intervals between the n date-time in times } \description{ \code{interval()} creates an \linkS4class{Interval} object with the specified start and end dates. If the start date occurs before the end date, the interval will be positive. Otherwise, it will be negative. Character vectors in ISO 8601 format are suported from v1.7.2. \code{\%--\%} Creates an interval that covers the range spanned by two dates. It replaces the original behavior of \pkg{lubridate}, which created an interval by default whenever two date-times were subtracted. \code{int_start()} and \code{int_start<-()} are accessors the start date of an interval. Note that changing the start date of an interval will change the length of the interval, since the end date will remain the same. \code{int_end()} and \code{int_end<-()} are accessors the end date of an interval. Note that changing the end date of an interval will change the length of the interval, since the start date will remain the same. \code{int_flip()} reverses the order of the start date and end date in an interval. The new interval takes place during the same timespan as the original interval, but has the opposite direction. \code{int_shift()} shifts the start and end dates of an interval up or down the timeline by a specified amount. Note that this may change the exact length of the interval if the interval is shifted by a Period object. Intervals shifted by a Duration or difftime object will retain their exact length in seconds. \code{int_overlaps()} tests if two intervals overlap. \code{int_standardize()} ensures all intervals in an interval object are positive. If an interval is not positive, flip it so that it retains its endpoints but becomes positive. \code{int_aligns()} tests if two intervals share an endpoint. The direction of each interval is ignored. int_align tests whether the earliest or latest moments of each interval occur at the same time. \code{int_diff()} returns the intervals that occur between the elements of a vector of date-times. \code{int_diff()} is similar to the POSIXt and Date methods of \code{\link[=diff]{diff()}}, but returns an \linkS4class{Interval} object instead of a difftime object. } \details{ Intervals are time spans bound by two real date-times. Intervals can be accurately converted to either period or duration objects using \code{\link[=as.period]{as.period()}}, \code{\link[=as.duration]{as.duration()}}. Since an interval is anchored to a fixed history of time, both the exact number of seconds that passed and the number of variable length time units that occurred during the interval can be calculated. } \examples{ interval(ymd(20090201), ymd(20090101)) date1 <- ymd_hms("2009-03-08 01:59:59") date2 <- ymd_hms("2000-02-29 12:00:00") interval(date2, date1) interval(date1, date2) span <- interval(ymd(20090101), ymd(20090201)) ### ISO Intervals interval("2007-03-01T13:00:00Z/2008-05-11T15:30:00Z") interval("2007-03-01T13:00:00Z/P1Y2M10DT2H30M") interval("P1Y2M10DT2H30M/2008-05-11T15:30:00Z") interval("2008-05-11/P2H30M") ### More permisive parsing (as long as there are no intermittent / characters) interval("2008 05 11/P2hours 30minutes") interval("08 05 11/P 2h 30m") is.interval(period(months= 1, days = 15)) # FALSE is.interval(interval(ymd(20090801), ymd(20090809))) # TRUE int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) int_start(int) int_start(int) <- ymd("2001-06-01") int int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) int_end(int) int_end(int) <- ymd("2002-06-01") int int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) int_length(int) int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) int_flip(int) int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) int_shift(int, duration(days = 11)) int_shift(int, duration(hours = -1)) int1 <- interval(ymd("2001-01-01"), ymd("2002-01-01")) int2 <- interval(ymd("2001-06-01"), ymd("2002-06-01")) int3 <- interval(ymd("2003-01-01"), ymd("2004-01-01")) int_overlaps(int1, int2) # TRUE int_overlaps(int1, int3) # FALSE int <- interval(ymd("2002-01-01"), ymd("2001-01-01")) int_standardize(int) int1 <- interval(ymd("2001-01-01"), ymd("2002-01-01")) int2 <- interval(ymd("2001-06-01"), ymd("2002-01-01")) int3 <- interval(ymd("2003-01-01"), ymd("2004-01-01")) int_aligns(int1, int2) # TRUE int_aligns(int1, int3) # FALSE dates <- now() + days(1:10) int_diff(dates) } \seealso{ \linkS4class{Interval}, \code{\link[=as.interval]{as.interval()}}, \code{\link{\%within\%}} } lubridate/man/fit_to_timeline.Rd0000644000176200001440000000546113201152061016436 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/update.r \name{fit_to_timeline} \alias{fit_to_timeline} \title{Fit a POSIXlt date-time to the timeline} \usage{ fit_to_timeline(lt, class = "POSIXct", simple = FALSE) } \arguments{ \item{lt}{a POSIXlt date-time object.} \item{class}{a character string that describes what type of object to return, POSIXlt or POSIXct. Defaults to POSIXct. This is an optimization to avoid needless conversions.} \item{simple}{if TRUE, \pkg{lubridate} makes no attempt to detect meaningless time-dates or to correct time zones. No NAs are produced and the most meaningful valid dates are returned instead. See examples.} } \value{ a POSIXct or POSIXlt object that contains no illusory date-times } \description{ The POSIXlt format allows you to create instants that do not exist in real life due to daylight savings time and other conventions. fit_to_timeline matches POSIXlt date-times to a real times. If an instant does not exist, fit to timeline will replace it with an NA. If an instant does exist, but has been paired with an incorrect timezone/daylight savings time combination, fit_to_timeline returns the instant with the correct combination. } \examples{ \dontrun{ tricky <- structure(list(sec = c(5, 0, 0, -1), min = c(0L, 5L, 5L, 0L), hour = c(2L, 0L, 2L, 2L), mday = c(4L, 4L, 14L, 4L), mon = c(10L, 10L, 2L, 10L), year = c(112L, 112L, 110L, 112L), wday = c(0L, 0L, 0L, 0L), yday = c(308L, 308L, 72L, 308L), isdst = c(1L, 0L, 0L, 1L)), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst"), class = c("POSIXlt", "POSIXt"), tzone = c("America/Chicago", "CST", "CDT")) tricky ## [1] "2012-11-04 02:00:00 CDT" Doesn't exist because clocks "fall back" to 1:00 CST ## [2] "2012-11-04 00:05:00 CST" Times are still CDT, not CST at this instant ## [3] "2010-03-14 02:00:00 CDT" DST gap ## [4] "2012-11-04 01:59:59 CDT" Does exist, but has deceptive internal structure fit_to_timeline(tricky) ## Returns: ## [1] "2012-11-04 02:00:00 CST" instant paired with correct tz & DST combination ## [2] "2012-11-04 00:05:00 CDT" instant paired with correct tz & DST combination ## [3] NA - fake time changed to NA (compare to as.POSIXct(tricky)) ## [4] "2012-11-04 01:59:59 CDT" -real instant, left as is fit_to_timeline(tricky, simple = TRUE) ## Returns valid time-dates by extrapolating CDT and CST zones: ## [1] "2012-11-04 01:00:05 CST" "2012-11-04 01:05:00 CDT" ## [3] "2010-03-14 03:05:00 CDT" "2012-11-04 01:59:59 CDT" } } lubridate/man/DateTimeUpdate.Rd0000644000176200001440000000322213201152061016114 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/update.r \name{DateTimeUpdate} \alias{DateTimeUpdate} \alias{update.POSIXt} \title{Changes the components of a date object} \usage{ \method{update}{POSIXt}(object, ..., roll = FALSE, week_start = getOption("lubridate.week.start", 7), simple = NULL) } \arguments{ \item{object}{a date-time object} \item{...}{named arguments: years, months, ydays, wdays, mdays, days, hours, minutes, seconds, tzs (time zone compnent)} \item{roll}{logical. If \code{TRUE}, and the resulting date-time lands on a non-existent civil time instant (DST, 29th February, etc.) roll the date till next valid point. When \code{FALSE}, the default, produce NA for non existing date-times.} \item{week_start}{week starting day (Default is 7, Sunday). Set \code{lubridate.week.start} option to control this.} \item{simple}{logical. Deprecated. Same as \code{roll}.} } \value{ a date object with the requested elements updated. The object will retain its original class unless an element is updated which the original class does not support. In this case, the date returned will be a POSIXlt date object. } \description{ \code{update.Date()} and \code{update.POSIXt()} return a date with the specified elements updated. Elements not specified will be left unaltered. update.Date and update.POSIXt do not add the specified values to the existing date, they substitute them for the appropriate parts of the existing date. } \examples{ date <- ymd("2009-02-10") update(date, year = 2010, month = 1, mday = 1) update(date, year =2010, month = 13, mday = 1) update(date, minute = 10, second = 3) } \keyword{chron} \keyword{manip} lubridate/man/is.difftime.Rd0000644000176200001440000000117213201152061015460 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/difftimes.r \name{is.difftime} \alias{is.difftime} \title{Is x a difftime object?} \usage{ is.difftime(x) } \arguments{ \item{x}{an R object} } \value{ TRUE if x is a difftime object, FALSE otherwise. } \description{ Is x a difftime object? } \examples{ is.difftime(as.Date("2009-08-03")) # FALSE is.difftime(make_difftime(days = 12.4)) # TRUE } \seealso{ \code{\link[=is.instant]{is.instant()}}, \code{\link[=is.timespan]{is.timespan()}}, \code{\link[=is.interval]{is.interval()}}, \code{\link[=is.period]{is.period()}}. } \keyword{chron} \keyword{logic} lubridate/man/week.Rd0000644000176200001440000000245613201152061014220 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-week.r \name{week} \alias{week} \alias{week<-} \alias{isoweek} \alias{epiweek} \title{Get/set weeks component of a date-time} \usage{ week(x) week(x) <- value isoweek(x) epiweek(x) } \arguments{ \item{x}{a date-time object. Must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, or fts object.} \item{value}{a numeric object} } \value{ the weeks element of x as an integer number } \description{ \code{week()} returns the number of complete seven day periods that have occurred between the date and January 1st, plus one. \code{isoweek()} returns the week as it would appear in the ISO 8601 system, which uses a reoccurring leap week. \code{epiweek()} is the US CDC version of epidemiological week. It follows same rules as \code{isoweek()} but starts on Sunday. In other parts of the world the convention is to start epidemiological weeks on Monday, which is the same as \code{isoweek}. } \examples{ x <- ymd("2012-03-26") week(x) week(x) <- 1 week(x) <- 54 week(x) > 3 } \references{ \url{http://en.wikipedia.org/wiki/ISO_week_date} \url{http://www.cmmcp.org/epiweek.htm} } \seealso{ \code{\link[=isoyear]{isoyear()}} } \keyword{chron} \keyword{manip} \keyword{utilities} lubridate/man/tz.Rd0000644000176200001440000000464513234630403013733 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-tz.r \name{tz} \alias{tz} \alias{tz<-} \title{Get/set time zone component of a date-time} \usage{ tz(x) tz(x) <- value } \arguments{ \item{x}{a date-time object of class a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, fts or anything else that can be coerced to POSIXlt with as.POSIXlt} \item{value}{timezone value to be assigned to \code{x}'s \code{tzone} attribute} } \value{ the first element of x's tzone attribute vector as a character string. If no tzone attribute exists, tz returns "GMT". } \description{ Time zones are stored as character strings in an attribute of date-time objects. tz returns a date's time zone attribute. When used as a settor, it changes the time zone attribute. R does not come with a predefined list zone names, but relies on the user's OS to interpret time zone names. As a result, some names will be recognized on some computers but not others. Most computers, however, will recognize names in the timezone data base originally compiled by Arthur Olson. These names normally take the form "Country/City." A convenient listing of these timezones can be found at \url{http://en.wikipedia.org/wiki/List_of_tz_database_time_zones}. } \details{ Setting tz does not update a date-time to display the same moment as measured at a different time zone. See \code{\link[=with_tz]{with_tz()}}. Setting a new time zone creates a new date-time. The numerical value of the hours element stays the same, only the time zone attribute is replaced. This creates a new date-time that occurs an integer value of hours before or after the original date-time. If x is of a class that displays all date-times in the GMT timezone, such as chron, then R will update the number in the hours element to display the new date-time in the GMT timezone. For a description of the time zone attribute, see \code{\link[base:timezones]{base::timezones()}} or \link[base:DateTimeClasses]{base::DateTimeClasses}. } \examples{ x <- ymd("2012-03-26") tz(x) tz(x) <- "GMT" x \dontrun{ tz(x) <- "America/New_York" x tz(x) <- "America/Chicago" x tz(x) <- "America/Los_Angeles" x tz(x) <- "Pacific/Honolulu" x tz(x) <- "Pacific/Auckland" x tz(x) <- "Europe/London" x tz(x) <- "Europe/Berlin" x Sys.setenv(TZ = "UTC") now() tz(now()) Sys.unsetenv("TZ") } } \keyword{chron} \keyword{manip} \keyword{methods} \keyword{utilities} lubridate/man/date_decimal.Rd0000644000176200001440000000136013201152061015651 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/decimal-dates.r \name{date_decimal} \alias{date_decimal} \title{Converts a decimal to a date} \usage{ date_decimal(decimal, tz = "UTC") } \arguments{ \item{decimal}{a numeric object} \item{tz}{the time zone required} } \value{ a POSIXct object, whose year corresponds to the integer part of decimal. The months, days, hours, minutes and seconds elements are picked so the date-time will accurately represent the fraction of the year expressed by decimal. } \description{ Converts a decimal to a date } \examples{ date <- ymd("2009-02-10") decimal <- decimal_date(date) # 2009.11 date_decimal(decimal) # "2009-02-10 UTC" } \keyword{chron} \keyword{manip} \keyword{methods} lubridate/man/period_to_seconds.Rd0000644000176200001440000000145213201152061016762 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/periods.r \name{period_to_seconds} \alias{period_to_seconds} \alias{seconds_to_period} \title{Contrive a period to/from a given number of seconds} \usage{ period_to_seconds(x) seconds_to_period(x) } \arguments{ \item{x}{A numeric object. The number of seconds to coerce into a period.} } \value{ A number (period) that roughly equates to the period (seconds) given. } \description{ \code{period_to_seconds()} approximately converts a period to seconds assuming there are 365.25 days in a calendar year and 365.25/12 days in a month. \code{seconds_to_period()} create a period that has the maximum number of non-zero elements (days, hours, minutes, seconds). This computation is exact because it doesn't involve years or months. } lubridate/man/lubridate-package.Rd0000644000176200001440000002046513201152061016631 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/package.r \docType{package} \name{lubridate-package} \alias{lubridate} \alias{lubridate-package} \title{Dates and times made easy with lubridate} \description{ Lubridate provides tools that make it easier to parse and manipulate dates. These tools are grouped below by common purpose. More information about each function can be found in its help documentation. } \section{Parsing dates}{ Lubridate's parsing functions read strings into R as POSIXct date-time objects. Users should choose the function whose name models the order in which the year ('y'), month ('m') and day ('d') elements appear the string to be parsed: \code{\link[=dmy]{dmy()}}, \code{\link[=myd]{myd()}}, \code{\link[=ymd]{ymd()}}, \code{\link[=ydm]{ydm()}}, \code{\link[=dym]{dym()}}, \code{\link[=mdy]{mdy()}}, \code{\link[=ymd_hms]{ymd_hms()}}). A very flexible and user friendly parser is provided by \code{\link[=parse_date_time]{parse_date_time()}}. Lubridate can also parse partial dates from strings into \linkS4class{Period} objects with the functions \code{\link[=hm]{hm()}}, \code{\link[=hms]{hms()}} and \code{\link[=ms]{ms()}}. Lubridate has an inbuilt very fast POSIX parser. Most of the \code{\link[=strptime]{strptime()}} formats and various extensions are supported for English locales. See \code{\link[=parse_date_time]{parse_date_time()}} for more details. } \section{Manipulating dates}{ Lubridate distinguishes between moments in time (known as \code{\link[=instants]{instants()}}) and spans of time (known as time spans, see \linkS4class{Timespan}). Time spans are further separated into \linkS4class{Duration}, \linkS4class{Period} and \linkS4class{Interval} objects. } \section{Instants}{ Instants are specific moments of time. Date, POSIXct, and POSIXlt are the three object classes Base R recognizes as instants. \code{\link[=is.Date]{is.Date()}} tests whether an object inherits from the Date class. \code{\link[=is.POSIXt]{is.POSIXt()}} tests whether an object inherits from the POSIXlt or POSIXct classes. \code{\link[=is.instant]{is.instant()}} tests whether an object inherits from any of the three classes. \code{\link[=now]{now()}} returns the current system time as a POSIXct object. \code{\link[=today]{today()}} returns the current system date. For convenience, 1970-01-01 00:00:00 is saved to \code{\link[=origin]{origin()}}. This is the instant from which POSIXct times are calculated. Try unclass(now()) to see the numeric structure that underlies POSIXct objects. Each POSIXct object is saved as the number of seconds it occurred after 1970-01-01 00:00:00. Conceptually, instants are a combination of measurements on different units (i.e, years, months, days, etc.). The individual values for these units can be extracted from an instant and set with the accessor functions \code{\link[=second]{second()}}, \code{\link[=minute]{minute()}}, \code{\link[=hour]{hour()}}, \code{\link[=day]{day()}}, \code{\link[=yday]{yday()}}, \code{\link[=mday]{mday()}}, \code{\link[=wday]{wday()}}, \code{\link[=week]{week()}}, \code{\link[=month]{month()}}, \code{\link[=year]{year()}}, \code{\link[=tz]{tz()}}, and \code{\link[=dst]{dst()}}. Note: the accessor functions are named after the singular form of an element. They shouldn't be confused with the period helper functions that have the plural form of the units as a name (e.g, \code{\link[=seconds]{seconds()}}). } \section{Rounding dates}{ Instants can be rounded to a convenient unit using the functions \code{\link[=ceiling_date]{ceiling_date()}}, \code{\link[=floor_date]{floor_date()}} and \code{\link[=round_date]{round_date()}}. } \section{Time zones}{ Lubridate provides two helper functions for working with time zones. \code{\link[=with_tz]{with_tz()}} changes the time zone in which an instant is displayed. The clock time displayed for the instant changes, but the moment of time described remains the same. \code{\link[=force_tz]{force_tz()}} changes only the time zone element of an instant. The clock time displayed remains the same, but the resulting instant describes a new moment of time. } \section{Timespans}{ A timespan is a length of time that may or may not be connected to a particular instant. For example, three months is a timespan. So is an hour and a half. Base R uses difftime class objects to record timespans. However, people are not always consistent in how they expect time to behave. Sometimes the passage of time is a monotone progression of instants that should be as mathematically reliable as the number line. On other occasions time must follow complex conventions and rules so that the clock times we see reflect what we expect to observe in terms of daylight, season, and congruence with the atomic clock. To better navigate the nuances of time, \pkg{lubridate} creates three additional timespan classes, each with its own specific and consistent behavior: \linkS4class{Interval}, \linkS4class{Period} and \linkS4class{Duration}. \code{\link[=is.difftime]{is.difftime()}} tests whether an object inherits from the difftime class. \code{\link[=is.timespan]{is.timespan()}} tests whether an object inherits from any of the four timespan classes. } \section{Durations}{ Durations measure the exact amount of time that occurs between two instants. This can create unexpected results in relation to clock times if a leap second, leap year, or change in daylight savings time (DST) occurs in the interval. Functions for working with durations include \code{\link[=is.duration]{is.duration()}}, \code{\link[=as.duration]{as.duration()}} and \code{\link[=duration]{duration()}}. \code{\link[=dseconds]{dseconds()}}, \code{\link[=dminutes]{dminutes()}}, \code{\link[=dhours]{dhours()}}, \code{\link[=ddays]{ddays()}}, \code{\link[=dweeks]{dweeks()}} and \code{\link[=dyears]{dyears()}} convenient lengths. } \section{Periods}{ Periods measure the change in clock time that occurs between two instants. Periods provide robust predictions of clock time in the presence of leap seconds, leap years, and changes in DST. Functions for working with periods include \code{\link[=is.period]{is.period()}}, \code{\link[=as.period]{as.period()}} and \code{\link[=period]{period()}}. \code{\link[=seconds]{seconds()}}, \code{\link[=minutes]{minutes()}}, \code{\link[=hours]{hours()}}, \code{\link[=days]{days()}}, \code{\link[=weeks]{weeks()}}, \code{\link[=months]{months()}} and \code{\link[=years]{years()}} quickly create periods of convenient lengths. } \section{Intervals}{ Intervals are timespans that begin at a specific instant and end at a specific instant. Intervals retain complete information about a timespan. They provide the only reliable way to convert between periods and durations. Functions for working with intervals include \code{\link[=is.interval]{is.interval()}}, \code{\link[=as.interval]{as.interval()}}, \code{\link[=interval]{interval()}}, \code{\link[=int_shift]{int_shift()}}, \code{\link[=int_flip]{int_flip()}}, \code{\link[=int_aligns]{int_aligns()}}, \code{\link[=int_overlaps]{int_overlaps()}}, and \code{\link{\%within\%}}. Intervals can also be manipulated with intersect, union, and setdiff(). } \section{Miscellaneous}{ \code{\link[=decimal_date]{decimal_date()}} converts an instant to a decimal of its year. \code{\link[=leap_year]{leap_year()}} tests whether an instant occurs during a leap year. \code{\link[=pretty_dates]{pretty_dates()}} provides a method of making pretty breaks for date-times \link{lakers} is a data set that contains information about the Los Angeles Lakers 2008-2009 basketball season. } \references{ Garrett Grolemund, Hadley Wickham (2011). Dates and Times Made Easy with lubridate. Journal of Statistical Software, 40(3), 1-25. \url{http://www.jstatsoft.org/v40/i03/}. } \seealso{ Useful links: \itemize{ \item \url{http://lubridate.tidyverse.org} \item \url{https://github.com/tidyverse/lubridate} \item Report bugs at \url{https://github.com/tidyverse/lubridate/issues} } } \author{ \strong{Maintainer}: Vitalie Spinu \email{spinuvit@gmail.com} Authors: \itemize{ \item Garrett Grolemund \item Hadley Wickham } Other contributors: \itemize{ \item Ian Lyttle [contributor] \item Imanuel Constigan [contributor] \item Jason Law [contributor] \item Doug Mitarotonda [contributor] \item Joseph Larmarange [contributor] \item Jonathan Boiser [contributor] \item Chel Hee Lee [contributor] } } \keyword{internal} lubridate/man/Interval-class.Rd0000644000176200001440000000224113201152061016144 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/intervals.r \docType{class} \name{Interval-class} \alias{Interval-class} \alias{intervals} \title{Interval class} \description{ Interval is an S4 class that extends the \linkS4class{Timespan} class. An Interval object records one or more spans of time. Intervals record these timespans as a sequence of seconds that begin at a specified date. Since intervals are anchored to a precise moment of time, they can accurately be converted to \linkS4class{Period} or \linkS4class{Duration} class objects. This is because we can observe the length in seconds of each period that begins on a specific date. Contrast this to a generalized period, which may not have a consistent length in seconds (e.g. the number of seconds in a year will change if it is a leap year). } \details{ Intervals can be both negative and positive. Negative intervals progress backwards from the start date; positive intervals progress forwards. Interval class objects have two slots: .Data, a numeric object equal to the number of seconds in the interval; and start, a POSIXct object that specifies the time when the interval starts. } lubridate/man/day.Rd0000644000176200001440000000432513201152061014037 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-day.r \name{day} \alias{day} \alias{mday} \alias{wday} \alias{qday} \alias{yday} \alias{day<-} \alias{mday<-} \alias{qday<-} \alias{wday<-} \alias{yday<-} \title{Get/set days component of a date-time} \usage{ day(x) mday(x) wday(x, label = FALSE, abbr = TRUE, week_start = getOption("lubridate.week.start", 7), locale = Sys.getlocale("LC_TIME")) qday(x) yday(x) day(x) <- value mday(x) <- value qday(x) <- value wday(x, week_start = getOption("lubridate.week.start", 7)) <- value yday(x) <- value } \arguments{ \item{x}{a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, or fts object.} \item{label}{logical. Only available for wday. TRUE will display the day of the week as an ordered factor of character strings, such as "Sunday." FALSE will display the day of the week as a number.} \item{abbr}{logical. Only available for wday. FALSE will display the day of the week as an ordered factor of character strings, such as "Sunday." TRUE will display an abbreviated version of the label, such as "Sun". abbr is disregarded if label = FALSE.} \item{week_start}{day on which week starts following ISO conventions - 1 means Monday, 7 means Sunday (default). You can set \code{lubridate.week.start} option to control this parameter globally.} \item{locale}{locale to use for day names. Default to current locale.} \item{value}{a numeric object} } \value{ \code{wday()} returns the day of the week as a decimal number or an ordered factor if label is \code{TRUE}. } \description{ Get/set days component of a date-time } \details{ \code{day()} and \code{day<-()} are aliases for \code{mday()} and \code{mday<-()} respectively. } \examples{ x <- as.Date("2009-09-02") wday(x) #4 wday(ymd(080101)) wday(ymd(080101), label = TRUE, abbr = FALSE) wday(ymd(080101), label = TRUE, abbr = TRUE) wday(ymd(080101) + days(-2:4), label = TRUE, abbr = TRUE) x <- as.Date("2009-09-02") yday(x) #245 mday(x) #2 yday(x) <- 1 #"2009-01-01" yday(x) <- 366 #"2010-01-01" mday(x) > 3 } \seealso{ \code{\link[=yday]{yday()}}, \code{\link[=mday]{mday()}} } \keyword{chron} \keyword{manip} \keyword{methods} \keyword{utilities} lubridate/man/month.Rd0000644000176200001440000000250313201152061014403 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-month.r \name{month} \alias{month} \alias{month<-} \title{Get/set months component of a date-time} \usage{ month(x, label = FALSE, abbr = TRUE, locale = Sys.getlocale("LC_TIME")) month(x) <- value } \arguments{ \item{x}{a date-time object} \item{label}{logical. TRUE will display the month as a character string such as "January." FALSE will display the month as a number.} \item{abbr}{logical. FALSE will display the month as a character string label, such as "January". TRUE will display an abbreviated version of the label, such as "Jan". abbr is disregarded if label = FALSE.} \item{locale}{for month, locale to use for month names. Default to current locale.} \item{value}{a numeric object} } \value{ the months element of x as a number (1-12) or character string. 1 = January. } \description{ Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. } \examples{ x <- ymd("2012-03-26") month(x) month(x) <- 1 month(x) <- 13 month(x) > 3 month(ymd(080101)) month(ymd(080101), label = TRUE) month(ymd(080101), label = TRUE, abbr = FALSE) month(ymd(080101) + months(0:11), label = TRUE) } \keyword{chron} \keyword{manip} \keyword{methods} \keyword{utilities} lubridate/man/local_time.Rd0000644000176200001440000000200213201152061015360 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/time-zones.r \name{local_time} \alias{local_time} \title{Get local time from a date-time vector.} \usage{ local_time(dt, tz = NULL, units = "secs") } \arguments{ \item{dt}{a date-time object.} \item{tz}{a character vector of timezones for which to compute the local time.} \item{units}{passed directly to \code{\link[=as.difftime]{as.difftime()}}.} } \description{ \code{local_time} retrieves day clock time in specified time zones. Computation is vectorized over both \code{dt} and \code{tz} arguments, the shortest is recycled in accordance with standard R rules. } \examples{ x <- ymd_hms(c("2009-08-07 01:02:03", "2009-08-07 10:20:30")) local_time(x, units = "secs") local_time(x, units = "hours") local_time(x, "Europe/Amsterdam") local_time(x, "Europe/Amsterdam") == local_time(with_tz(x, "Europe/Amsterdam")) x <- ymd_hms("2009-08-07 01:02:03") local_time(x, c("America/New_York", "Europe/Amsterdam", "Asia/Shanghai"), unit = "hours") } lubridate/man/reclass_timespan.Rd0000644000176200001440000000100313201152061016604 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/coercion.r \name{reclass_timespan} \alias{reclass_timespan} \alias{reclass_timespan,ANY,Duration-method} \alias{reclass_timespan,ANY,Interval-method} \alias{reclass_timespan,ANY,Period-method} \alias{reclass_timespan,ANY,difftime-method} \title{Convenience method to reclass timespans post-modification.} \usage{ reclass_timespan(new, orig) } \description{ Convenience method to reclass timespans post-modification. } \keyword{internal} lubridate/man/is.instant.Rd0000644000176200001440000000135313201152061015352 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/instants.r \name{is.instant} \alias{is.instant} \alias{instant} \alias{instants} \alias{is.timepoint} \title{Is x a date-time object?} \usage{ is.instant(x) is.timepoint(x) } \arguments{ \item{x}{an R object} } \value{ TRUE if x is a POSIXct, POSIXlt, or Date object, FALSE otherwise. } \description{ An instant is a specific moment in time. Most common date-time objects (e.g, POSIXct, POSIXlt, and Date objects) are instants. } \examples{ is.instant(as.Date("2009-08-03")) # TRUE is.timepoint(5) # FALSE } \seealso{ \code{\link[=is.timespan]{is.timespan()}}, \code{\link[=is.POSIXt]{is.POSIXt()}}, \code{\link[=is.Date]{is.Date()}} } \keyword{chron} \keyword{logic} lubridate/man/now.Rd0000644000176200001440000000134313201152061014062 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/instants.r \name{now} \alias{now} \title{The current time} \usage{ now(tzone = "") } \arguments{ \item{tzone}{a character vector specifying which time zone you would like the current time in. tzone defaults to your computer's system timezone. You can retrieve the current time in the Universal Coordinated Time (UTC) with now("UTC").} } \value{ the current date and time as a POSIXct object } \description{ The current time } \examples{ now() now("GMT") now("") now() == now() # would be TRUE if computer processed both at the same instant now() < now() # TRUE now() > now() # FALSE } \seealso{ \code{\link[=here]{here()}} } \keyword{chron} \keyword{utilities} lubridate/man/am.Rd0000644000176200001440000000064213201152061013655 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/am-pm.r \name{am} \alias{am} \alias{pm} \title{Does date time occur in the am or pm?} \usage{ am(x) pm(x) } \arguments{ \item{x}{a date-time object} } \value{ TRUE or FALSE depending on whether x occurs in the am or pm } \description{ Does date time occur in the am or pm? } \examples{ x <- ymd("2012-03-26") am(x) pm(x) } \keyword{chron} lubridate/man/hour.Rd0000644000176200001440000000130013201152061014225 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-hour.r \name{hour} \alias{hour} \alias{hour<-} \title{Get/set hours component of a date-time} \usage{ hour(x) hour(x) <- value } \arguments{ \item{x}{a date-time object} \item{value}{numeric value to be assigned to the \code{hour} component} } \value{ the hours element of x as a decimal number } \description{ Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. } \examples{ x <- ymd("2012-03-26") hour(x) hour(x) <- 1 hour(x) <- 25 hour(x) > 2 } \keyword{chron} \keyword{manip} \keyword{methods} \keyword{utilities} lubridate/man/as.interval.Rd0000644000176200001440000000370613201152061015512 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/coercion.r \name{as.interval} \alias{as.interval} \alias{as.interval,numeric-method} \alias{as.interval,difftime-method} \alias{as.interval,Interval-method} \alias{as.interval,Duration-method} \alias{as.interval,Period-method} \alias{as.interval,POSIXt-method} \alias{as.interval,logical-method} \title{Change an object to an \code{interval}} \usage{ as.interval(x, start, ...) } \arguments{ \item{x}{a duration, difftime, period, or numeric object that describes the length of the interval} \item{start}{a POSIXt or Date object that describes when the interval begins} \item{...}{additional arguments to pass to as.interval} } \value{ an interval object } \description{ as.interval changes difftime, Duration, Period and numeric class objects to intervals that begin at the specified date-time. Numeric objects are first coerced to timespans equal to the numeric value in seconds. } \details{ as.interval can be used to create accurate transformations between Period objects, which measure time spans in variable length units, and Duration objects, which measure timespans as an exact number of seconds. A start date- time must be supplied to make the conversion. Lubridate uses this start date to look up how many seconds each variable length unit (e.g. month, year) lasted for during the time span described. See \code{\link[=as.duration]{as.duration()}}, \code{\link[=as.period]{as.period()}}. } \examples{ diff <- make_difftime(days = 31) #difftime as.interval(diff, ymd("2009-01-01")) as.interval(diff, ymd("2009-02-01")) dur <- duration(days = 31) #duration as.interval(dur, ymd("2009-01-01")) as.interval(dur, ymd("2009-02-01")) per <- period(months = 1) #period as.interval(per, ymd("2009-01-01")) as.interval(per, ymd("2009-02-01")) as.interval(3600, ymd("2009-01-01")) #numeric } \seealso{ \code{\link[=interval]{interval()}} } \keyword{chron} \keyword{classes} \keyword{manip} \keyword{methods} lubridate/man/today.Rd0000644000176200001440000000111213201152061014371 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/instants.r \name{today} \alias{today} \title{The current date} \usage{ today(tzone = "") } \arguments{ \item{tzone}{a character vector specifying which time zone you would like to find the current date of. tzone defaults to the system time zone set on your computer.} } \value{ the current date as a Date object } \description{ The current date } \examples{ today() today("GMT") today() == today("GMT") # not always true today() < as.Date("2999-01-01") # TRUE (so far) } \keyword{chron} \keyword{utilities} lubridate/man/is.Date.Rd0000644000176200001440000000105213201152061014543 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/Dates.r \name{is.Date} \alias{is.Date} \title{Is x a Date object?} \usage{ is.Date(x) } \arguments{ \item{x}{an R object} } \value{ TRUE if x is a Date object, FALSE otherwise. } \description{ Is x a Date object? } \examples{ is.Date(as.Date("2009-08-03")) # TRUE is.Date(difftime(now() + 5, now())) # FALSE } \seealso{ \code{\link[=is.instant]{is.instant()}}, \code{\link[=is.timespan]{is.timespan()}}, \code{\link[=is.POSIXt]{is.POSIXt()}} } \keyword{chron} \keyword{logic} lubridate/man/leap_year.Rd0000644000176200001440000000126213201152061015220 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/leap-years.r \name{leap_year} \alias{leap_year} \title{Is a year a leap year?} \usage{ leap_year(date) } \arguments{ \item{date}{a date-time object or a year} } \value{ TRUE if x is a leap year, FALSE otherwise } \description{ If x is a recognized date-time object, leap_year will return whether x occurs during a leap year. If x is a number, leap_year returns whether it would be a leap year under the Gregorian calendar. } \examples{ x <- as.Date("2009-08-02") leap_year(x) # FALSE leap_year(2009) # FALSE leap_year(2008) # TRUE leap_year(1900) # FALSE leap_year(2000) # TRUE } \keyword{chron} \keyword{logic} lubridate/man/force_tz.Rd0000644000176200001440000000500213263116135015100 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/time-zones.r \name{force_tz} \alias{force_tz} \alias{force_tzs} \title{Replace time zone to create new date-time} \usage{ force_tz(time, tzone = "", roll = FALSE) force_tzs(time, tzones, tzone_out = "UTC", roll = FALSE) } \arguments{ \item{time}{a POSIXct, POSIXlt, Date, chron date-time object, or a data.frame object. When a data.frame all POSIXt elements of a data.frame are processed with \code{force_tz()} and new data.frame is returned.} \item{tzone}{a character string containing the time zone to convert to. R must recognize the name contained in the string as a time zone on your system.} \item{roll}{logical. If TRUE, and \code{time} falls into the DST-break, assume the next valid civil time, otherwise return NA. See examples.} \item{tzones}{character vector of timezones to be "enforced" on \code{time} time stamps. If \code{time} and \code{tzones} lengths differ, the smaller one is recycled in accordance with usual R conventions.} \item{tzone_out}{timezone of the returned date-time vector (for \code{force_tzs}).} } \value{ a POSIXct object in the updated time zone } \description{ \code{force_tz} returns the date-time that has the same clock time as input time, but in the new time zone. \code{force_tzs} is the parallel version of \code{force_tz}, meaning that every element from \code{time} argument is matched with the corresponding time zone in \code{tzones} argument. } \details{ Although the new date-time has the same clock time (e.g. the same values in the year, month, days, etc. elements) it is a different moment of time than the input date-time. As R date-time vectors cannot hold elements with non-uniform time zones, \code{force_tzs} returns a vector with time zone \code{tzone_out}, UTC by default. } \examples{ x <- ymd_hms("2009-08-07 00:00:01", tz = "America/New_York") force_tz(x, "UTC") force_tz(x, "Europe/Amsterdam") ## DST skip: y <- ymd_hms("2010-03-14 02:05:05 UTC") force_tz(y, "America/New_York", roll=FALSE) force_tz(y, "America/New_York", roll=TRUE) ## Heterogeneous time-zones: x <- ymd_hms(c("2009-08-07 00:00:01", "2009-08-07 01:02:03")) force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam")) force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam"), tzone_out = "America/New_York") x <- ymd_hms("2009-08-07 00:00:01") force_tzs(x, tzones = c("America/New_York", "Europe/Amsterdam")) } \seealso{ \code{\link[=with_tz]{with_tz()}}, \code{\link[=local_time]{local_time()}} } \keyword{chron} \keyword{manip} lubridate/man/rollback.Rd0000644000176200001440000000224413201152061015051 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ops-m+.r \name{rollback} \alias{rollback} \title{Roll back date to last day of previous month} \usage{ rollback(dates, roll_to_first = FALSE, preserve_hms = TRUE) } \arguments{ \item{dates}{A POSIXct, POSIXlt or Date class object.} \item{roll_to_first}{Rollback to the first day of the month instead of the last day of the previous month} \item{preserve_hms}{Retains the same hour, minute, and second information? If FALSE, the new date will be at 00:00:00.} } \value{ A date-time object of class POSIXlt, POSIXct or Date, whose day has been adjusted to the last day of the previous month, or to the first day of the month. } \description{ rollback changes a date to the last day of the previous month or to the first day of the month. Optionally, the new date can retain the same hour, minute, and second information. } \examples{ date <- ymd("2010-03-03") rollback(date) dates <- date + months(0:2) rollback(dates) date <- ymd_hms("2010-03-03 12:44:22") rollback(date) rollback(date, roll_to_first = TRUE) rollback(date, preserve_hms = FALSE) rollback(date, roll_to_first = TRUE, preserve_hms = FALSE) } lubridate/man/with_tz.Rd0000644000176200001440000000225013201152061014745 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/time-zones.r \name{with_tz} \alias{with_tz} \title{Get date-time in a different time zone} \usage{ with_tz(time, tzone = "") } \arguments{ \item{time}{a POSIXct, POSIXlt, Date, chron date-time object or a data.frame object. When a data.frame all POSIXt elements of a data.frame are processed with \code{with_tz()} and new data.frame is returned.} \item{tzone}{a character string containing the time zone to convert to. R must recognize the name contained in the string as a time zone on your system.} } \value{ a POSIXct object in the updated time zone } \description{ with_tz returns a date-time as it would appear in a different time zone. The actual moment of time measured does not change, just the time zone it is measured in. with_tz defaults to the Universal Coordinated time zone (UTC) when an unrecognized time zone is inputted. See \code{\link[=Sys.timezone]{Sys.timezone()}} for more information on how R recognizes time zones. } \examples{ x <- ymd_hms("2009-08-07 00:00:01", tz = "America/New_York") with_tz(x, "GMT") } \seealso{ \code{\link[=force_tz]{force_tz()}} } \keyword{chron} \keyword{manip} lubridate/man/Period-class.Rd0000644000176200001440000000562113201152061015607 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/periods.r \docType{class} \name{Period-class} \alias{Period-class} \title{Period class} \description{ Period is an S4 class that extends the \linkS4class{Timespan} class. Periods track the change in the "clock time" between two date-times. They are measured in common time related units: years, months, days, hours, minutes, and seconds. Each unit except for seconds must be expressed in integer values. } \details{ The exact length of a period is not defined until the period is placed at a specific moment of time. This is because the precise length of one year, month, day, etc. can change depending on when it occurs due to daylight savings, leap years, and other conventions. A period can be associated with a specific moment in time by coercing it to an \linkS4class{Interval} object with \code{\link[=as.interval]{as.interval()}} or by adding it to a date-time with "+". Periods provide a method for measuring generalized timespans when we wish to model clock times. Periods will attain intuitive results at this task even when leap years, leap seconds, gregorian days, daylight savings changes, and other events happen during the period. Because Period represents imprecise amount of time it cannot be compared to precise timestamps as Durations and Intervals are. You need to explicitely conver to durations. See \linkS4class{Duration}. The logic that guides arithmetic with periods can be unintuitive. Starting with version 1.3.0, \pkg{lubridate} enforces the reversible property of arithmetic (e.g. a date + period - period = date) by returning an NA if you create an implausible date by adding periods with months or years units to a date. For example, adding one month to January 31st, 2013 results in February 31st, 2013, which is not a real date. \pkg{lubridate} users have argued in the past that February 31st, 2013 should be rolled over to March 3rd, 2013 or rolled back to February 28, 2013. However, each of these corrections would destroy the reversibility of addition (Mar 3 - one month == Feb 3 != Jan 31, Feb 28 - one month == Jan 28 != Jan 31). If you would like to add and subtract months in a way that rolls the results back to the last day of a month (when appropriate) use the special operators, \code{\link{\%m+\%}}, \code{\link{\%m-\%}} or a bit more flexible \code{\link[=add_with_rollback]{add_with_rollback()}}. Period class objects have six slots. 1) .Data, a numeric object. The apparent amount of seconds to add to the period. 2) minute, a numeric object. The apparent amount of minutes to add to the period. 3) hour, a numeric object. The apparent amount of hours to add to the period.4) day, a numeric object. The apparent amount of days to add to the period.5) month, a numeric object. The apparent amount of months to add to the period. 6) year, a numeric object. The apparent amount of years to add to the period. } \keyword{internal} lubridate/man/duration.Rd0000644000176200001440000001024413234630403015113 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/durations.r \name{duration} \alias{duration} \alias{dseconds} \alias{dminutes} \alias{dhours} \alias{ddays} \alias{dweeks} \alias{dyears} \alias{dmilliseconds} \alias{dmicroseconds} \alias{dnanoseconds} \alias{dpicoseconds} \alias{is.duration} \title{Create a duration object.} \usage{ duration(num = NULL, units = "seconds", ...) dseconds(x = 1) dminutes(x = 1) dhours(x = 1) ddays(x = 1) dweeks(x = 1) dyears(x = 1) dmilliseconds(x = 1) dmicroseconds(x = 1) dnanoseconds(x = 1) dpicoseconds(x = 1) is.duration(x) } \arguments{ \item{num}{the number or a character vector of time units. In string representation all unambiguous name units and abbreviations and ISO 8601 formats are supported; 'm' stands for month and 'M' for minutes unless ISO 8601 "P" modifier is present (see examples). Fractional units are supported.} \item{units}{a character string that specifies the type of units that num refers to. When \code{num} is character, this argument is ignored.} \item{...}{a list of time units to be included in the duration and their amounts. Seconds, minutes, hours, days, and weeks are supported.} \item{x}{numeric value of the number of units to be contained in the duration.} } \value{ a duration object } \description{ \code{duration()} creates a duration object with the specified values. Entries for different units are cumulative. durations display as the number of seconds in a time span. When this number is large, durations also display an estimate in larger units,; however, the underlying object is always recorded as a fixed number of seconds. For display and creation purposes, units are converted to seconds using their most common lengths in seconds. Minutes = 60 seconds, hours = 3600 seconds, days = 86400 seconds, weeks = 604800. Units larger than weeks are not used due to their variability. } \details{ Durations record the exact number of seconds in a time span. They measure the exact passage of time but do not always align with measurements made in larger units of time such as hours, months and years. This is because the length of larger time units can be affected by conventions such as leap years and Daylight Savings Time. Base R provides a second class for measuring durations, the difftime class. Duration objects can be easily created with the helper functions \code{\link[=dweeks]{dweeks()}}, \code{\link[=ddays]{ddays()}}, \code{\link[=dminutes]{dminutes()}}, \code{\link[=dseconds]{dseconds()}}. These objects can be added to and subtracted to date- times to create a user interface similar to object oriented programming. } \examples{ ### Separate period and units vectors duration(90, "seconds") duration(1.5, "minutes") duration(-1, "days") ### Units as arguments duration(day = -1) duration(second = 90) duration(minute = 1.5) duration(mins = 1.5) duration(second = 3, minute = 1.5, hour = 2, day = 6, week = 1) duration(hour = 1, minute = -60) ### Parsing duration("2M 1sec") duration("2hours 2minutes 1second") duration("2d 2H 2M 2S") duration("2days 2hours 2mins 2secs") # Missing numerals default to 1. Repeated units are added up. duration("day day") ### ISO 8601 parsing duration("P3Y6M4DT12H30M5S") duration("P23DT23H") # M stands for months duration("10DT10M") # M stands for minutes duration("P23DT60H 20min 100 sec") # mixing ISO and lubridate style parsing # Comparison with characters (from v1.6.0) duration("day 2 sec") > "day 1sec" ## ELEMENTARY CONSTRUCTORS: dseconds(1) dminutes(3.5) x <- ymd_hms("2009-08-03", tz="America/Chicago") x + ddays(1) + dhours(6) + dminutes(30) x + ddays(100) - dhours(8) class(as.Date("2009-08-09") + ddays(1)) # retains Date class as.Date("2009-08-09") + dhours(12) class(as.Date("2009-08-09") + dhours(12)) # converts to POSIXt class to accomodate time units dweeks(1) - ddays(7) c(1:3) * dhours(1) # compare DST handling to durations boundary <- ymd_hms("2009-03-08 01:59:59", tz="America/Chicago") boundary + days(1) # period boundary + ddays(1) # duration is.duration(as.Date("2009-08-03")) # FALSE is.duration(duration(days = 12.4)) # TRUE } \seealso{ \code{\link[=as.duration]{as.duration()}} \linkS4class{Duration} } \keyword{chron} \keyword{classes} lubridate/man/as_date.Rd0000644000176200001440000000471713263137567014715 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/coercion.r \docType{methods} \name{as_date} \alias{as_date} \alias{as_date,ANY-method} \alias{as_date,POSIXt-method} \alias{as_date,numeric-method} \alias{as_date,character-method} \alias{as_datetime} \alias{as_datetime,POSIXt-method} \alias{as_datetime,numeric-method} \alias{as_datetime,character-method} \alias{as_datetime,ANY-method} \title{Convert an object to a date or date-time} \usage{ as_date(x, ...) \S4method{as_date}{ANY}(x, ...) \S4method{as_date}{POSIXt}(x, tz = NULL) \S4method{as_date}{numeric}(x, origin = lubridate::origin) \S4method{as_date}{character}(x, tz = NULL, format = NULL) as_datetime(x, ...) \S4method{as_datetime}{POSIXt}(x, tz = "UTC") \S4method{as_datetime}{numeric}(x, origin = lubridate::origin, tz = "UTC") \S4method{as_datetime}{character}(x, tz = "UTC", format = NULL) \S4method{as_datetime}{ANY}(x, tz = "UTC") } \arguments{ \item{x}{a vector of \link{POSIXt}, numeric or character objects} \item{...}{further arguments to be passed to specific methods (see above).} \item{tz}{a time zone name (default: time zone of the POSIXt object \code{x}). See \code{\link[=OlsonNames]{OlsonNames()}}.} \item{origin}{a Date object, or something which can be coerced by \code{as.Date(origin, ...)} to such an object (default: the Unix epoch of "1970-01-01"). Note that in this instance, \code{x} is assumed to reflect the number of days since \code{origin} at \code{"UTC"}.} \item{format}{format argument for character methods. When supplied parsing is performed by \code{\link[=strptime]{strptime()}}. For this reason consider using specialized parsing functions in lubridate.} } \value{ a vector of \link{Date} objects corresponding to \code{x}. } \description{ Convert an object to a date or date-time } \section{Compare to base R}{ These are drop in replacements for \code{\link[=as.Date]{as.Date()}} and \code{\link[=as.POSIXct]{as.POSIXct()}}, with a few tweaks to make them work more intuitively. \itemize{ \item \code{as_date()} ignores the timezone attribute, resulting in a more intuitive conversion (see examples) \item Both functions provide a default origin argument for numeric vectors. \item \code{as_datetime()} defaults to using UTC. } } \examples{ dt_utc <- ymd_hms("2010-08-03 00:50:50") dt_europe <- ymd_hms("2010-08-03 00:50:50", tz="Europe/London") c(as_date(dt_utc), as.Date(dt_utc)) c(as_date(dt_europe), as.Date(dt_europe)) ## need not supply origin as_date(10) } lubridate/man/mplus.Rd0000644000176200001440000000615313201152061014423 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/ops-m+.r \name{\%m+\%} \alias{\%m+\%} \alias{m+} \alias{m-} \alias{\%m-\%} \alias{\%m+\%,ANY,ANY-method} \alias{\%m-\%,ANY,ANY-method} \alias{\%m+\%,Period,ANY-method} \alias{\%m+\%,ANY,Period-method} \alias{\%m-\%,Period,ANY-method} \alias{\%m-\%,ANY,Period-method} \alias{\%m+\%,Duration,ANY-method} \alias{\%m+\%,ANY,Duration-method} \alias{\%m-\%,Duration,ANY-method} \alias{\%m-\%,ANY,Duration-method} \alias{\%m+\%,Interval,ANY-method} \alias{\%m+\%,ANY,Interval-method} \alias{\%m-\%,Interval,ANY-method} \alias{\%m-\%,ANY,Interval-method} \alias{add_with_rollback} \title{Add and subtract months to a date without exceeding the last day of the new month} \usage{ e1 \%m+\% e2 add_with_rollback(e1, e2, roll_to_first = FALSE, preserve_hms = TRUE) } \arguments{ \item{e1}{A period or a date-time object of class \link{POSIXlt}, \link{POSIXct} or \link{Date}.} \item{e2}{A period or a date-time object of class \link{POSIXlt}, \link{POSIXct} or \link{Date}. Note that one of e1 and e2 must be a period and the other a date-time object.} \item{roll_to_first}{rollback to the first day of the month instead of the last day of the previous month (passed to \code{\link[=rollback]{rollback()}})} \item{preserve_hms}{retains the same hour, minute, and second information? If FALSE, the new date will be at 00:00:00 (passed to \code{\link[=rollback]{rollback()}})} } \value{ A date-time object of class POSIXlt, POSIXct or Date } \description{ Adding months frustrates basic arithmetic because consecutive months have different lengths. With other elements, it is helpful for arithmetic to perform automatic roll over. For example, 12:00:00 + 61 seconds becomes 12:01:01. However, people often prefer that this behavior NOT occur with months. For example, we sometimes want January 31 + 1 month = February 28 and not March 3. \code{\%m+\%} performs this type of arithmetic. Date \code{\%m+\%} months(n) always returns a date in the nth month after Date. If the new date would usually spill over into the n + 1th month, \code{\%m+\%} will return the last day of the nth month (\code{\link[=rollback]{rollback()}}). Date \code{\%m-\%} months(n) always returns a date in the nth month before Date. \code{add_with_rollback()} provides additional functionality to \code{\%m+\%} and \code{\%m-\%}. It allows rollback to first day of the month instead of the last day of the previous month and controls whether HMS component of the end date is preserved or not. } \details{ \code{\%m+\%} and \code{\%m-\%} handle periods with components less than a month by first adding/substracting months and then performing usual arithmetics with smaller units. \code{\%m+\%} and \code{\%m-\%} should be used with caution as they are not one-to-one operations and results for either will be sensitive to the order of operations. } \examples{ jan <- ymd_hms("2010-01-31 03:04:05") jan + months(1:3) # Feb 31 and April 31 returned as NA # NA "2010-03-31 03:04:05 UTC" NA jan \%m+\% months(1:3) # No rollover leap <- ymd("2012-02-29") "2012-02-29 UTC" leap \%m+\% years(1) leap \%m+\% years(-1) leap \%m-\% years(1) } lubridate/man/date.Rd0000644000176200001440000000165413201152061014201 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-date.R \name{date} \alias{date} \alias{date<-} \title{Get/set date component of a date-time} \usage{ date(x) date(x) <- value } \arguments{ \item{x}{a date-time object} \item{value}{an object for which the \code{date()} function is defined} } \value{ the date of x as a Date } \description{ Date-time must be a POSIXct, POSIXlt, Date, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. } \details{ \code{date()} does not yet support years before 0 C.E. Also \code{date()} is not defined for Period objects. } \examples{ x <- ymd_hms("2012-03-26 23:12:13", tz = "America/New_York") date(x) as.Date(x) # by default as.Date assumes you want to know the date in UTC as.Date(x, tz = "America/New_York") date(x) <- as.Date("2000-01-02") x } \keyword{chron} \keyword{manip} \keyword{methods} \keyword{utilities} lubridate/man/minute.Rd0000644000176200001440000000127413201152061014563 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/accessors-minute.r \name{minute} \alias{minute} \alias{minute<-} \title{Get/set minutes component of a date-time} \usage{ minute(x) minute(x) <- value } \arguments{ \item{x}{a date-time object} \item{value}{numeric value to be assigned} } \value{ the minutes element of x as a decimal number } \description{ Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects. } \examples{ x <- ymd("2012-03-26") minute(x) minute(x) <- 1 minute(x) <- 61 minute(x) > 2 } \keyword{chron} \keyword{manip} \keyword{methods} \keyword{utilities} lubridate/man/as.duration.Rd0000644000176200001440000000345613201152061015515 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/coercion.r \name{as.duration} \alias{as.duration} \alias{as.duration,numeric-method} \alias{as.duration,logical-method} \alias{as.duration,difftime-method} \alias{as.duration,Interval-method} \alias{as.duration,Duration-method} \alias{as.duration,Period-method} \alias{as.duration,character-method} \title{Change an object to a duration} \usage{ as.duration(x, ...) } \arguments{ \item{x}{Object to be coerced to a duration} \item{...}{Parameters passed to other methods. Currently unused.} } \value{ A duration object } \description{ as.duration changes Interval, Period and numeric class objects to Duration objects. Numeric objects are changed to Duration objects with the seconds unit equal to the numeric value. } \details{ Durations are exact time measurements, whereas periods are relative time measurements. See \linkS4class{Period}. The length of a period depends on when it occurs. Hence, a one to one mapping does not exist between durations and periods. When used with a period object, as.duration provides an inexact estimate of the length of the period; each time unit is assigned its most common number of seconds. A period of one month is converted to 2628000 seconds (approximately 30.42 days). This ensures that 12 months will sum to 365 days, or one normal year. For an exact transformation, first transform the period to an interval with \code{\link[=as.interval]{as.interval()}}. } \examples{ span <- interval(ymd("2009-01-01"), ymd("2009-08-01")) #interval as.duration(span) as.duration(10) # numeric dur <- duration(hours = 10, minutes = 6) as.numeric(dur, "hours") as.numeric(dur, "minutes") } \seealso{ \linkS4class{Duration}, \code{\link[=duration]{duration()}} } \keyword{chron} \keyword{classes} \keyword{manip} \keyword{methods} lubridate/man/parse_date_time.Rd0000644000176200001440000003165613234630403016425 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/parse.r \name{parse_date_time} \alias{parse_date_time} \alias{parse_date_time2} \alias{fast_strptime} \title{User friendly date-time parsing functions} \usage{ parse_date_time(x, orders, tz = "UTC", truncated = 0, quiet = FALSE, locale = Sys.getlocale("LC_TIME"), select_formats = .select_formats, exact = FALSE, train = TRUE, drop = FALSE) parse_date_time2(x, orders, tz = "UTC", exact = FALSE, lt = FALSE, cutoff_2000 = 68L) fast_strptime(x, format, tz = "UTC", lt = TRUE, cutoff_2000 = 68L) } \arguments{ \item{x}{a character or numeric vector of dates} \item{orders}{a character vector of date-time formats. Each order string is series of formatting characters as listed \code{\link[base:strptime]{base::strptime()}} but might not include the "\%" prefix, for example "ymd" will match all the possible dates in year, month, day order. Formatting orders might include arbitrary separators. These are discarded. See details for implemented formats.} \item{tz}{a character string that specifies the time zone with which to parse the dates} \item{truncated}{integer, number of formats that can be missing. The most common type of irregularity in date-time data is the truncation due to rounding or unavailability of the time stamp. If the \code{truncated} parameter is non-zero \code{parse_date_time()} also checks for truncated formats. For example, if the format order is "ymdHMS" and \code{truncated = 3}, \code{parse_date_time()} will correctly parse incomplete dates like \code{2012-06-01 12:23}, \code{2012-06-01 12} and \code{2012-06-01}. \bold{NOTE:} The \code{ymd} family of functions are based on \code{strptime()} which currently fails to parse \code{\%Y-\%m} formats.} \item{quiet}{logical. When TRUE progress messages are not printed, and "no formats found" error is surpresed and the function simply returns a vector of NAs. This mirrors the behavior of base R functions \code{strptime()} and \code{as.POSIXct()}. Default is \code{FALSE}.} \item{locale}{locale to be used, see \link{locales}. On linux systems you can use \code{system("locale -a")} to list all the installed locales.} \item{select_formats}{A function to select actual formats for parsing from a set of formats which matched a training subset of \code{x}. It receives a named integer vector and returns a character vector of selected formats. Names of the input vector are formats (not orders) that matched the training set. Numeric values are the number of dates (in the training set) that matched the corresponding format. You should use this argument if the default selection method fails to select the formats in the right order. By default the formats with most formating tokens (\%) are selected and \%Y counts as 2.5 tokens (so that it has a priority over \%y\%m). See examples.} \item{exact}{logical. If \code{TRUE}, the \code{orders} parameter is interpreted as an exact \code{strptime()} format and no training or guessing are performed (i.e. \code{train}, \code{drop} parameters are irrelevant).} \item{train}{logical, default TRUE. Whether to train formats on a subset of the input vector. The result of this is that supplied orders are sorted according to performance on this training set, which commonly results in increased performance. Please note that even when \code{train} is \code{FALSE} (and \code{exact} is \code{FALSE}) guessing of the actual formats is still performed on a pseudo-random subset of the original input vector. This might result in \code{All formats failed to parse} error. See notes below.} \item{drop}{logical, default FALSE. Whether to drop formats that didn't match on the training set. If FALSE, unmatched on the training set formats are tried as a last resort at the end of the parsing queue. Applies only when \code{train=TRUE}. Seating this parameter to TRUE might slightly speed up parsing in situations involving many formats. Prior to v1.7.0 this parameter was implicitly TRUE, which resulted in occasional surprising behavior when rare patterns where not present in the training set.} \item{lt}{logical. If TRUE returned object is of class POSIXlt, and POSIXct otherwise. For compatibility with base \code{strptime} function default is TRUE for \code{fast_strptime} and FALSE for \code{parse_date_time2}.} \item{cutoff_2000}{integer. For \code{y} format, two-digit numbers smaller or equal to \code{cutoff_2000} are parsed as 20th's century, 19th's otherwise. Available only for functions relying on \code{lubridate}s internal parser.} \item{format}{a character string of formats. It should include all the separators and each format must be prefixed with %, just as in the format argument of \code{strptime()}.} } \value{ a vector of POSIXct date-time objects } \description{ \code{parse_date_time()} parses an input vector into POSIXct date-time object. It differs from \code{\link[base:strptime]{base::strptime()}} in two respects. First, it allows specification of the order in which the formats occur without the need to include separators and \code{\%} prefix. Such a formating argument is refered to as "order". Second, it allows the user to specify several format-orders to handle heterogeneous date-time character representations. \code{parse_date_time2()} is a fast C parser of numeric orders. \code{fast_strptime()} is a fast C parser of numeric formats only that accepts explicit format arguments, just as \code{\link[base:strptime]{base::strptime()}}. } \details{ When several format-orders are specified, \code{parse_date_time()} selects (guesses) format-orders based on a training sub-set of the input strings. After guessing the formats are ordered according to the performance on the training set and applied recursively on the entire input vector. You can disable training with \code{train=FALSE}. \code{parse_date_time()}, and all derived functions, such as \code{ymd_hms()}, \code{ymd()} etc, will drop into \code{fast_strptime()} instead of \code{strptime()} whenever the guessed from the input data formats are all numeric. The list below contains formats recognized by \pkg{lubridate}. For numeric formats leading 0s are optional. As compared to base \code{strptime()}, some of the formats are new or have been extended for efficiency reasons. These formats are marked with "*". The fast parsers \code{parse_date_time2()} and \code{fast_strptime()} accept only formats marked with "!". \describe{ \item{\code{a}}{Abbreviated weekday name in the current locale. (Also matches full name)} \item{\code{A}}{Full weekday name in the current locale. (Also matches abbreviated name). You don't need to specify \code{a} and \code{A} formats explicitly. Wday is automatically handled if \code{preproc_wday = TRUE}} \item{\code{b}!}{Abbreviated or full month name in the current locale. The C parser currently understands only English month names.} \item{\code{B}!}{Same as b.} \item{\code{d}!}{Day of the month as decimal number (01--31 or 0--31)} \item{\code{H}!}{Hours as decimal number (00--24 or 0--24).} \item{\code{I}!}{Hours as decimal number (01--12 or 1--12).} \item{\code{j}}{Day of year as decimal number (001--366 or 1--366).} \item{\code{q}!*}{Quarter (1--4). The quarter month is added to the parsed month if \code{m} format is present.} \item{\code{m}!*}{Month as decimal number (01--12 or 1--12). For \code{parse_date_time}. As a \pkg{lubridate} extension, also matches abbreviated and full months names as \code{b} and \code{B} formats. C parser understands only English month names.} \item{\code{M}!}{Minute as decimal number (00--59 or 0--59).} \item{\code{p}!}{AM/PM indicator in the locale. Normally used in conjunction with \code{I} and \bold{not} with \code{H}. But the \pkg{lubridate} C parser accepts H format as long as hour is not greater than 12. C parser understands only English locale AM/PM indicator.} \item{\code{S}!}{Second as decimal number (00--61 or 0--61), allowing for up to two leap-seconds (but POSIX-compliant implementations will ignore leap seconds).} \item{\code{OS}}{Fractional second.} \item{\code{U}}{Week of the year as decimal number (00--53 or 0--53) using Sunday as the first day 1 of the week (and typically with the first Sunday of the year as day 1 of week 1). The US convention.} \item{\code{w}}{Weekday as decimal number (0--6, Sunday is 0).} \item{\code{W}}{Week of the year as decimal number (00--53 or 0--53) using Monday as the first day of week (and typically with the first Monday of the year as day 1 of week 1). The UK convention.} \item{\code{y}!*}{Year without century (00--99 or 0--99). In \code{parse_date_time()} also matches year with century (Y format).} \item{\code{Y}!}{Year with century.} \item{\code{z}!*}{ISO8601 signed offset in hours and minutes from UTC. For example \code{-0800}, \code{-08:00} or \code{-08}, all represent 8 hours behind UTC. This format also matches the Z (Zulu) UTC indicator. Because strptime doesn't fully support ISO8601 this format is implemented as an union of 4 orders: Ou (Z), Oz (-0800), OO (-08:00) and Oo (-08). You can use these four orders as any other but it is rarely necessary. \code{parse_date_time2()} and \code{fast_strptime()} support all of the timezone formats.} \item{\code{Om}!*}{Matches numeric month and English alphabetic months (Both, long and abbreviated forms).} \item{\code{Op}!*}{Matches AM/PM English indicator.} \item{\code{r}*}{Matches \code{Ip} and \code{H} orders.} \item{\code{R}*}{Matches \code{HM} and\code{IMp} orders.} \item{\code{T}*}{Matches \code{IMSp}, \code{HMS}, and \code{HMOS} orders.} } } \note{ \code{parse_date_time()} (and the derivatives \code{ymd()}, \code{ymd_hms()} etc) rely on a sparse guesser that takes at most 501 elements from the supplied character vector in order to identify appropriate formats from the supplied orders. If you get the error \code{All formats failed to parse} and you are confident that your vector contains valid dates, you should either set \code{exact} argument to TRUE or use functions that don't perform format guessing (\code{fast_strptime()}, \code{parse_date_time2()} or \code{strptime()}). For performance reasons, when timezone is not UTC, \code{parse_date_time2()} and \code{fast_strptime()} perform no validity checks for daylight savings time. Thus, if your input string contains an invalid date time which falls into DST gap and \code{lt = TRUE} you will get an \code{POSIXlt} object with a non-existen time. If \code{lt = FALSE} your time instant will be adjusted to a valid time by adding an hour. See examples. If you want to get NA for invalid date-times use \code{\link[=fit_to_timeline]{fit_to_timeline()}} explicitly. } \examples{ ## ** orders are much easier to write ** x <- c("09-01-01", "09-01-02", "09-01-03") parse_date_time(x, "ymd") parse_date_time(x, "y m d") parse_date_time(x, "\%y\%m\%d") # "2009-01-01 UTC" "2009-01-02 UTC" "2009-01-03 UTC" ## ** heterogenuous date-times ** x <- c("09-01-01", "090102", "09-01 03", "09-01-03 12:02") parse_date_time(x, c("ymd", "ymd HM")) ## ** different ymd orders ** x <- c("2009-01-01", "02022010", "02-02-2010") parse_date_time(x, c("dmY", "ymd")) ## "2009-01-01 UTC" "2010-02-02 UTC" "2010-02-02 UTC" ## ** truncated time-dates ** x <- c("2011-12-31 12:59:59", "2010-01-01 12:11", "2010-01-01 12", "2010-01-01") parse_date_time(x, "Ymd HMS", truncated = 3) ## ** specifying exact formats and avoiding training and guessing ** parse_date_time(x, c("\%m-\%d-\%y", "\%m\%d\%y", "\%m-\%d-\%y \%H:\%M"), exact = TRUE) parse_date_time(c('12/17/1996 04:00:00','4/18/1950 0130'), c('\%m/\%d/\%Y \%I:\%M:\%S','\%m/\%d/\%Y \%H\%M'), exact = TRUE) ## ** quarters and partial dates ** parse_date_time(c("2016.2", "2016-04"), orders = "Yq") parse_date_time(c("2016", "2016-04"), orders = c("Y", "Ym")) ## ** fast parsing ** \dontrun{ options(digits.secs = 3) ## random times between 1400 and 3000 tt <- as.character(.POSIXct(runif(1000, -17987443200, 32503680000))) tt <- rep.int(tt, 1000) system.time(out <- as.POSIXct(tt, tz = "UTC")) system.time(out1 <- ymd_hms(tt)) # constant overhead on long vectors system.time(out2 <- parse_date_time2(tt, "YmdHMOS")) system.time(out3 <- fast_strptime(tt, "\%Y-\%m-\%d \%H:\%M:\%OS")) all.equal(out, out1) all.equal(out, out2) all.equal(out, out3) } ## ** how to use `select_formats` argument ** ## By default \%Y has precedence: parse_date_time(c("27-09-13", "27-09-2013"), "dmy") ## to give priority to \%y format, define your own select_format function: my_select <- function(trained, drop=FALSE, ...){ n_fmts <- nchar(gsub("[^\%]", "", names(trained))) + grepl("\%y", names(trained))*1.5 names(trained[ which.max(n_fmts) ]) } parse_date_time(c("27-09-13", "27-09-2013"), "dmy", select_formats = my_select) ## ** invalid times with "fast" parsing ** parse_date_time("2010-03-14 02:05:06", "YmdHMS", tz = "America/New_York") parse_date_time2("2010-03-14 02:05:06", "YmdHMS", tz = "America/New_York") parse_date_time2("2010-03-14 02:05:06", "YmdHMS", tz = "America/New_York", lt = TRUE) } \seealso{ \code{strptime()}, \code{\link[=ymd]{ymd()}}, \code{\link[=ymd_hms]{ymd_hms()}} } \keyword{chron} lubridate/man/make_datetime.Rd0000644000176200001440000000215013201152061016045 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/instants.r \name{make_datetime} \alias{make_datetime} \alias{make_date} \title{Efficient creation of date-times from numeric representations} \usage{ make_datetime(year = 1970L, month = 1L, day = 1L, hour = 0L, min = 0L, sec = 0, tz = "UTC") make_date(year = 1970L, month = 1L, day = 1L) } \arguments{ \item{year}{numeric year} \item{month}{numeric month} \item{day}{numeric day} \item{hour}{numeric hour} \item{min}{numeric minute} \item{sec}{numeric second} \item{tz}{time zone. Defaults to UTC.} } \description{ \code{make_datetime()} is a very fast drop-in replacement for \code{\link[base:ISOdate]{base::ISOdate()}} and \code{\link[base:ISOdatetime]{base::ISOdatetime()}}. \code{make_date()} produces objects of class \code{Date}. } \details{ Input vectors are silently recycled. All inputs except \code{sec} are silently converted to integer vectors; \code{sec} can be either integer or double. } \examples{ make_datetime(year = 1999, month = 12, day = 22, sec = 10) make_datetime(year = 1999, month = 12, day = 22, sec = c(10, 11)) } lubridate/man/time_length.Rd0000644000176200001440000000304213201152061015554 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/timespans.r, R/intervals.r \docType{methods} \name{time_length} \alias{time_length} \alias{time_length,Interval-method} \title{Compute the exact length of a time span} \usage{ time_length(x, unit = "second") \S4method{time_length}{Interval}(x, unit = "second") } \arguments{ \item{x}{a duration, period, difftime or interval} \item{unit}{a character string that specifies with time units to use} } \value{ the length of the interval in the specified unit. A negative number connotes a negative interval or duration } \description{ Compute the exact length of a time span } \details{ When \code{x} is an \linkS4class{Interval} object and \code{unit} are years or months, \code{time_length()} takes into account the fact that all months and years don't have the same number of days. When \code{x} is a \linkS4class{Duration}, \linkS4class{Period} or \code{\link[=difftime]{difftime()}} object, length in months or years is based on their most common lengths in seconds (see \code{\link[=timespan]{timespan()}}). } \examples{ int <- interval(ymd("1980-01-01"), ymd("2014-09-18")) time_length(int, "week") # Exact age time_length(int, "year") # Age at last anniversary trunc(time_length(int, "year")) # Example of difference between intervals and durations int <- interval(ymd("1900-01-01"), ymd("1999-12-31")) time_length(int, "year") time_length(as.duration(int), "year") } \seealso{ \code{\link[=timespan]{timespan()}} } \keyword{chron} \keyword{math} \keyword{methods} \keyword{period} lubridate/man/DateCoercion.Rd0000644000176200001440000000045113201152061015615 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/coercion.r \name{DateCoercion} \alias{DateCoercion} \title{Convert a variety of date-time classes to POSIXlt and POSIXct} \description{ Convert a variety of date-time classes to POSIXlt and POSIXct } \keyword{internal} lubridate/man/period.Rd0000644000176200001440000001314313234630403014551 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/periods.r \name{period} \alias{period} \alias{periods} \alias{is.period} \alias{seconds} \alias{minutes} \alias{hours} \alias{days} \alias{weeks} \alias{years} \alias{milliseconds} \alias{microseconds} \alias{nanoseconds} \alias{picoseconds} \alias{months.numeric} \title{Create or parse period objects} \usage{ period(num = NULL, units = "second", ...) is.period(x) seconds(x = 1) minutes(x = 1) hours(x = 1) days(x = 1) weeks(x = 1) years(x = 1) milliseconds(x = 1) microseconds(x = 1) nanoseconds(x = 1) picoseconds(x = 1) \method{months}{numeric}(x, abbreviate) } \arguments{ \item{num}{a numeric or character vector. A character vector can specify periods in a convenient shorthand format or ISO 8601 specification. All unambiguous name units and abbreviations are supported, "m" stands for months, "M" for minutes unless ISO 8601 "P" modifier is present (see examples). Fractional units are supported but the fractional part is always converted to seconds.} \item{units}{a character vector that lists the type of units to be used. The units in units are matched to the values in num according to their order. When \code{num} is character, this argument is ignored.} \item{...}{a list of time units to be included in the period and their amounts. Seconds, minutes, hours, days, weeks, months, and years are supported. Normally only one of \code{num} or \code{...} are present. If both are present, the periods are concatenated.} \item{x}{Any R object for \code{is.periods} and a numeric value of the number of units for elementary constructors. With the exception of seconds(), x must be an integer.} \item{abbreviate}{Ignored. For consistency with S3 generic in base namespace.} } \value{ a period object } \description{ \code{period()} creates or parses a period object with the specified values. } \details{ Within a Period object, time units do not have a fixed length (except for seconds) until they are added to a date-time. The length of each time unit will depend on the date-time to which it is added. For example, a year that begins on 2009-01-01 will be 365 days long. A year that begins on 2012-01-01 will be 366 days long. When math is performed with a period object, each unit is applied separately. How the length of a period is distributed among its units is non-trivial. For example, when leap seconds occur 1 minute is longer than 60 seconds. Periods track the change in the "clock time" between two date-times. They are measured in common time related units: years, months, days, hours, minutes, and seconds. Each unit except for seconds must be expressed in integer values. Besides the main constructor and parser \code{\link[=period]{period()}}, period objects can also be created with the specialized functions \code{\link[=years]{years()}}, \code{\link[=months]{months()}}, \code{\link[=weeks]{weeks()}}, \code{\link[=days]{days()}}, \code{\link[=hours]{hours()}}, \code{\link[=minutes]{minutes()}}, and \code{\link[=seconds]{seconds()}}. These objects can be added to and subtracted to date-times to create a user interface similar to object oriented programming. Note: Arithmetic with periods can results in undefined behavior when non-existent dates are involved (such as February 29th). Please see \linkS4class{Period} for more details and \code{\link{\%m+\%}} and \code{\link[=add_with_rollback]{add_with_rollback()}} for alternative operations. Note: Arithmetic with periods can results in undefined behavior when non-existent dates are involved (such as February 29th in non-leap years). Please see \linkS4class{Period} for more details and \code{\link{\%m+\%}} and \code{\link[=add_with_rollback]{add_with_rollback()}} for alternative operations. } \examples{ ### Separate period and units vectors period(c(90, 5), c("second", "minute")) # "5M 90S" period(-1, "days") period(c(3, 1, 2, 13, 1), c("second", "minute", "hour", "day", "week")) period(c(1, -60), c("hour", "minute")) period(0, "second") ### Units as arguments period (second = 90, minute = 5) period(day = -1) period(second = 3, minute = 1, hour = 2, day = 13, week = 1) period(hour = 1, minute = -60) period(second = 0) period(c(1, -60), c("hour", "minute"), hour = c(1, 2), minute = c(3, 4)) ### Lubridate style parsing period("2M 1sec") period("2hours 2minutes 1second") period("2d 2H 2M 2S") period("2days 2hours 2mins 2secs") period("2 days, 2 hours, 2 mins, 2 secs") # Missing numerals default to 1. Repeated units are added up. duration("day day") ### ISO 8601 parsing period("P10M23DT23H") # M stands for months period("10DT10M") # M stands for minutes period("P3Y6M4DT12H30M5S") # M for both minutes and months period("P23DT60H 20min 100 sec") # mixing ISO and lubridate style parsing ### Comparison with characters (from v1.6.0) duration("day 2 sec") > "day 1sec" ### Elementary Constructors x <- ymd("2009-08-03") x + days(1) + hours(6) + minutes(30) x + days(100) - hours(8) class(as.Date("2009-08-09") + days(1)) # retains Date class as.Date("2009-08-09") + hours(12) class(as.Date("2009-08-09") + hours(12)) # converts to POSIXt class to accomodate time units years(1) - months(7) c(1:3) * hours(1) hours(1:3) # sequencing y <- ymd(090101) # "2009-01-01 CST" y + months(0:11) # compare DST handling to durations boundary <- ymd_hms("2009-03-08 01:59:59", tz="America/Chicago") boundary + days(1) # period boundary + ddays(1) # duration is.period(as.Date("2009-08-03")) # FALSE is.period(period(months= 1, days = 15)) # TRUE } \seealso{ \linkS4class{Period}, \code{\link[=period]{period()}}, \code{\link{\%m+\%}}, \code{\link[=add_with_rollback]{add_with_rollback()}} } \keyword{chron} \keyword{classes} lubridate/man/Duration-class.Rd0000644000176200001440000000207613201152061016153 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/durations.r \docType{class} \name{Duration-class} \alias{Duration-class} \alias{durations} \title{Duration class} \description{ Duration is an S4 class that extends the \linkS4class{Timespan} class. Durations record the exact number of seconds in a time span. They measure the exact passage of time but do not always align with measurements made in larger units of time such as hours, months and years. This is because the exact length of larger time units can be affected by conventions such as leap years and Daylight Savings Time. } \details{ Durations provide a method for measuring generalized timespans when we wish to treat time as a mathematical quantity that increases in a uniform, monotone manner along a continuous numberline. They allow exact comparisons with other durations. See \linkS4class{Period} for an alternative way to measure timespans that better preserves clock times. Durations class objects have one slot: .Data, a numeric object equal to the number of seconds in the duration. } lubridate/man/within-interval.Rd0000644000176200001440000000307713263134511016421 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/intervals.r \name{\%within\%} \alias{\%within\%} \alias{\%within\%,Interval,Interval-method} \alias{\%within\%,ANY,Interval-method} \alias{\%within\%,Date,list-method} \alias{\%within\%,POSIXt,list-method} \title{Tests whether a date or interval falls within an interval} \usage{ a \%within\% b } \arguments{ \item{a}{An interval or date-time object} \item{b}{An interval or a list of intervals (see examples)} } \value{ A logical } \description{ %within% returns TRUE if \code{a} falls within interval \code{b}. Both \code{a} and \code{b} are recycled according to standard R rules. If \code{b} is a list of intervals, \code{a} is checked if it falls within any of the intervals in \code{b}. If a is an interval, both its start and end dates must fall within b to return TRUE. } \examples{ int <- interval(ymd("2001-01-01"), ymd("2002-01-01")) int2 <- interval(ymd("2001-06-01"), ymd("2002-01-01")) ymd("2001-05-03") \%within\% int # TRUE int2 \%within\% int # TRUE ymd("1999-01-01") \%within\% int # FALSE ## recycling dates <- ymd(c("2014-12-20", "2014-12-30", "2015-01-01", "2015-01-03")) blackouts<- c(interval(ymd("2014-12-30"), ymd("2014-12-31")), interval(ymd("2014-12-30"), ymd("2015-01-03"))) dates \%within\% blackouts ## within ANY of the intervals of a list dates <- ymd(c("2014-12-20", "2014-12-30", "2015-01-01", "2015-01-03")) blackouts<- list(interval(ymd("2014-12-30"), ymd("2014-12-31")), interval(ymd("2014-12-30"), ymd("2015-01-03"))) dates \%within\% blackouts } lubridate/man/ymd.Rd0000644000176200001440000000770613263116135014073 0ustar liggesusers% Generated by roxygen2: do not edit by hand % Please edit documentation in R/parse.r \name{ymd} \alias{ymd} \alias{ydm} \alias{mdy} \alias{myd} \alias{dmy} \alias{dym} \alias{yq} \title{Parse dates with \strong{y}ear, \strong{m}onth, and \strong{d}ay components} \usage{ ymd(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) ydm(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) mdy(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) myd(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) dmy(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) dym(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME"), truncated = 0) yq(..., quiet = FALSE, tz = NULL, locale = Sys.getlocale("LC_TIME")) } \arguments{ \item{...}{a character or numeric vector of suspected dates} \item{quiet}{logical. When TRUE function evalueates without displaying customary messages.} \item{tz}{Time zone indicator. If NULL (default) a Date object is returned. Otherwise a POSIXct with time zone attribute set to \code{tz}.} \item{locale}{locale to be used, see \link{locales}. On linux systems you can use \code{system("locale -a")} to list all the installed locales.} \item{truncated}{integer. Number of formats that can be truncated.} } \value{ a vector of class POSIXct if tz argument is non-NULL or Date if tz is NULL (default) } \description{ Transforms dates stored in character and numeric vectors to Date or POSIXct objects (see \code{tz} argument). These functions recognize arbitrary non-digit separators as well as no separator. As long as the order of formats is correct, these functions will parse dates correctly even when the input vectors contain differently formatted dates. See examples. } \details{ In case of heterogeneous date formats \code{ymd()} family guesses formats based on a sub-set of the input vector. If the input vector contains many missing values or non-date strings, the sub-set might not contain meaningful dates and the date-time format won't be guessed resulting in "All formats failed to parse" error. In such cases please see \code{\link[=parse_date_time]{parse_date_time()}} for a more flexible parsing interface. If the \code{truncated} parameter is non-zero, the \code{ymd} functions also check for truncated formats. For example \code{ymd()} with \code{truncated = 2} will also parse incomplete dates like \code{2012-06} and \code{2012}. NOTE: The \code{ymd} family of functions are based on \code{parse_date_time()} and thus directly drop to the internal C parser for numeric months, but use R's \code{strptime()} for alphabetic months. This implies that some of the \code{strptime()}'s limitations are inherited by \pkg{lubridate}'s parser. For example, truncated formats (like \code{\%Y-\%b}) will not be parsed. Numeric truncated formats (like \code{\%Y-\%m}) are handled correctly by \pkg{lubridate}'s C parser. As of version 1.3.0, \pkg{lubridate}'s parse functions no longer return a message that displays which format they used to parse their input. You can change this by setting the \code{lubridate.verbose} option to \code{TRUE} with \code{options(lubridate.verbose = TRUE)}. } \examples{ x <- c("09-01-01", "09-01-02", "09-01-03") ymd(x) x <- c("2009-01-01", "2009-01-02", "2009-01-03") ymd(x) ymd(090101, 90102) now() > ymd(20090101) ## TRUE dmy(010210) mdy(010210) ## heterogenuous formats in a single vector: x <- c(20090101, "2009-01-02", "2009 01 03", "2009-1-4", "2009-1, 5", "Created on 2009 1 6", "200901 !!! 07") ymd(x) ## What lubridate might not handle: ## Extremely weird cases when one of the separators is "" and some of the ## formats are not in double digits might not be parsed correctly: \dontrun{ymd("201002-01", "201002-1", "20102-1") dmy("0312-2010", "312-2010")} } \seealso{ \code{\link[=parse_date_time]{parse_date_time()}} for an even more flexible low level mechanism. } \keyword{chron} lubridate/cleanup0000755000176200001440000000012513263152652013605 0ustar liggesusersrm -f src/*.a src/*.o src/*.so src/*.dylib src/*~ *~ ./src/*/*/*.o lubridate*.tar.gz