как рассчитать разницу между двумя датами
Вы можете использовать следующий синтаксис для вычисления разницы между двумя датами в кадре данных pandas:
df['diff_days'] =(df['end_date'] - df['start_date']) / np.timedelta64 ( 1 , 'D')
В этом конкретном примере вычисляется разница между датами в столбцах end_date и start_date в днях.
Обратите внимание, что мы можем заменить «D» в функции timedelta64() следующими значениями для вычисления разницы дат в разных единицах измерения:
- Вт : недели
- М : Месяцы
- Г : Годы
В следующих примерах показано, как на практике рассчитать разницу дат в кадре данных pandas.
Пример 1: вычислить разницу между двумя датами со столбцами даты и времениПредположим, у нас есть следующие Pandas DataFrame:
import pandas as pd #create DataFrame df = pd.DataFrame({'start_date ': pd. date_range (start='1/5/2020', periods= 6 , freq='W'), 'end_date ': pd.date_range (start='6/1/2020', periods= 6 , freq='M')}) #view DataFrame print(df) start_date end_date 0 2020-01-05 2020-06-30 1 2020-01-12 2020-07-31 2 2020-01-19 2020-08-31 3 2020-01-26 2020-09-30 4 2020-02-02 2020-10-31 5 2020-02-09 2020-11-30 #view dtype of each column in DataFrame df.dtypes start_date datetime64[ns] end_date datetime64[ns] dtype: object
Поскольку оба столбца в DataFrame уже имеют dtype datetime64 , мы можем использовать следующий синтаксис для вычисления разницы между датами начала и окончания:
import numpy as np #create new columns that contains date differences df['diff_days'] =(df['end_date'] - df['start_date']) / np.timedelta64 ( 1 , 'D') df['diff_weeks'] =(df['end_date'] - df['start_date']) / np.timedelta64 ( 1 , 'W') df['diff_months'] =(df['end_date'] - df['start_date']) / np.timedelta64 ( 1 , 'M') df['diff_years'] =(df['end_date'] - df['start_date']) / np. timedelta64 ( 1 , 'Y') #view updated DataFrame print(df) start_date end_date diff_days diff_weeks diff_months diff_years 0 2020-01-05 2020-06-30 177.0 25.285714 5.815314 0.484610 1 2020-01-12 2020-07-31 201.0 28.714286 6.603832 0.550319 2 2020-01-19 2020-08-31 225.0 32.142857 7.392349 0.616029 3 2020-01-26 2020-09-30 248.0 35.428571 8.148011 0.679001 4 2020-02-02 2020-10-31 272.0 38.857143 8.936528 0.744711 5 2020-02-09 2020-11-30 295.0 42.142857 9.692191 0.807683
Новые столбцы содержат разницу между датами начала и окончания в днях, неделях, месяцах и годах.
Пример 2. Расчет разницы между двумя датами со строковыми столбцамиПредположим, у нас есть следующие Pandas DataFrame:
import pandas as pd #create DataFrame df = pd.DataFrame({'start_date': ['2020-01-05', '2020-01-12', '2020-01-19'], 'end_date': ['2020-06-30', '2020-07-31', '2020-08-31']}) #view dtype of each column print(df.dtypes ) start_date object end_date object dtype: object
Поскольку ни один столбец в DataFrame не имеет dtype
import numpy as np #attempt to calculate date difference df['diff_days'] =(df['end_date'] - df['start_date']) / np. timedelta64 ( 1 , 'D') TypeError : unsupported operand type(s) for -: 'str' and 'str'
Сначала мы должны использовать pd.to_datetime для преобразования каждого столбца в формат даты и времени, прежде чем вычислять разницу между датами:
import numpy as np #convert columns to datetime df[['start_date',' end_date']] = df[['start_date',' end_date']].apply (pd.to_datetime ) #calculate difference between dates df['diff_days'] =(df['end_date'] - df['start_date']) / np.timedelta64 ( 1 , 'D') #view updated DataFrame print(df) start_date end_date diff_days 0 2020-01-05 2020-06-30 177.0 1 2020-01-12 2020-07-31 201.0 2 2020-01-19 2020-08-31 225.0
Поскольку мы сначала преобразовали каждый столбец в формат даты и времени, мы смогли успешно вычислить разницу между датами без каких-либо ошибок.
Дополнительные ресурсыВ следующих руководствах объясняется, как выполнять другие распространенные операции в pandas:
Как создать диапазон дат в Pandas
Как извлечь месяц из даты в Pandas
Как преобразовать отметку времени в дату и время в pandas
android — Расчет разницы между датами с учетом самих дат
Вопрос задан
Изменён 1 год 5 месяцев назад
Просмотрен 477 раз
Рассчитывается переменная содержащая разницу между датами
val d5razn = ChronoUnit. DAYS.between(d3parse, d4parse)
Но если считать разницу, например, между 01.02.2010 и 02.02.2010 — то расчет — 1 день. А мне нужно чтобы в итоге получался результат включающий обе эти даты — то есть 2 дня.
Мне нужно просто прибавлять 1 день
или есть какой-то другой способ или функция?
val d3: String = date3?.text.toString() val d4: String = date4?.text.toString() val d3parse = LocalDate.parse(d3, dateFormatInput) val d4parse = LocalDate.parse(d4, dateFormatInput) val d5razn = ChronoUnit.DAYS.between(d3parse, d4parse) outDaysText?.text = d5razn.toString()
- android
- kotlin
- дата
3
Метод between
возвращает число (long
) — просто прибавьте 1 без всяких дополнительных методов:
val d3 = "01.02.2010" val d4 = "02.02.2010" // val d3: String = date3?.text.toString() // val d4: String = date4?. text.toString() val dateFormatInput = DateTimeFormatter.ofPattern("dd.MM.yyyy") val d3parse = LocalDate.parse(d3, dateFormatInput) val d4parse = LocalDate.parse(d4, dateFormatInput) val d5razn = ChronoUnit.DAYS.between(d3parse, d4parse) + 1 println(d5razn) // Вывод: 2
7
Зарегистрируйтесь или войдите
Регистрация через Google
Регистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
ЧИСТРАБДНИ — служба поддержки Майкрософт
Excel
Формулы и функции
Дополнительные функции
Дополнительные функции
Функция ЧИСТРАБДНИ
Excel для Microsoft 365 Excel для Microsoft 365 для Mac Excel для Интернета Excel 2021 Excel 2021 для Mac Excel 2019 Excel 2019 для Mac Excel 2016 Excel 2016 для Mac Excel 2013 Excel 2010 Excel 2007 Excel для Mac 2011 Excel Starter 2010 Дополнительно. .. Меньше
В этой статье описаны синтаксис формулы и использование функции ЧИСТРАБДНИ в Microsoft Excel.
Описание
Возвращает количество полных рабочих дней между start_date и end_date. Рабочие дни не включают выходные и любые даты, указанные в праздничных днях. Используйте ЧИСТРАБДНИ для расчета вознаграждений работникам, которые начисляются на основе количества дней, отработанных в течение определенного срока.
Совет: Чтобы рассчитать полные рабочие дни между двумя датами с помощью параметров, указывающих, какие и сколько дней являются выходными, используйте функцию ЧИСТРАБДНИ.МЕЖД.
Синтаксис
ЧИСТРАБДНИ(дата_начала, дата_окончания, [праздники])
Синтаксис функции ЧИСТРАБДНИ имеет следующие аргументы:
Дата_начала Обязательно.
End_date Обязательный. Дата, представляющая дату окончания.
Праздники Необязательно. Необязательный диапазон из одной или нескольких дат для исключения из рабочего календаря, например государственные и федеральные праздники и плавающие праздники. Список может быть либо диапазоном ячеек, содержащих даты, либо константой массива порядковых номеров, представляющих даты.
Важно: Даты следует вводить с помощью функции ДАТА или в качестве результатов других формул или функций. Например, используйте DATE(2012,5,23) для 23 мая 2012 года. Если даты вводятся в виде текста, могут возникнуть проблемы.
Замечания
Microsoft Excel хранит даты в виде последовательных порядковых номеров, чтобы их можно было использовать в вычислениях. По умолчанию 1 января 19 г.00 — это порядковый номер 1, а 1 января 2012 года — порядковый номер 40909, потому что это 40 909 дней после 1 января 1900 года.
Если какой-либо аргумент не является допустимой датой, ЧИСТРАБДНИ возвращает #ЗНАЧ! значение ошибки.
Пример
Скопируйте данные примера из следующей таблицы и вставьте их в ячейку A1 нового рабочего листа Excel. Чтобы формулы отображали результаты, выберите их, нажмите F2, а затем нажмите клавишу ВВОД. При необходимости вы можете настроить ширину столбцов, чтобы увидеть все данные.
Дата | Описание | |
01.10.2012 | Дата начала проекта | |
01.03.2013 | Дата окончания проекта | |
22.11.2012 | Праздник | |
04. 12.2012 | Праздник | |
21.01.2013 | Праздник | |
Формула | Описание | Результат |
= ЧИСТРАБДНИ(A2,A3) | Количество рабочих дней между датой начала (01.10.2012) и датой окончания (01.03. 2013). | 110 |
=ЧИСТРАБДНИ(A2,A3,A4) | Количество рабочих дней между датой начала (01.10.2012) и датой окончания (01.03.2013), при этом выходной день 22.11.2012 считается нерабочим. | 109 |
=ЧИСТРАБДНИ(A2,A3,A4:A6) | Количество рабочих дней между датой начала (1.10.2012) и датой окончания (01.03.2013), при этом три праздничных дня считаются нерабочими. | 107 |
Верх страницы
Работа с датами и временем в R с использованием пакета lubridate
Иногда у нас есть данные с датами и/или временем, которыми мы хотим манипулировать или суммировать. Типичным примером в науках о здоровье является время обучения. Субъект может войти в исследование 12 февраля 2008 г. и выйти из него 4 ноября 2009 г. Сколько дней человек был в исследовании? (Не забывайте, что 2008 год был високосным; в феврале было 29 дней.) Каково было среднее время обучения по всем предметам?
Другим примером являются эксперименты, в которых участники измеряют время выполнения действия, применяют лечение к определенным участникам, а затем повторно измеряют время действия. Какова была разница во времени между испытуемыми, получавшими лечение, и теми, кто его не получал? Если наши данные хранятся и считываются как что-то вроде «01:23:03», нам нужно преобразовать их в секунды.
Пакет lubridate для среды статистических вычислений R был разработан, чтобы помочь нам работать с такими данными. Готовая базовая установка R также предоставляет функции для работы с датами и временем, но функции в пакете lubridate немного проще в использовании и запоминании.
Форматирование дат
Когда мы импортируем данные в R, даты и время обычно сохраняются как символ или фактор по умолчанию из-за таких символов, как «-», «:» и «/». (Хотя см. пакет readr для функций, которые пытаются автоматически анализировать дату и время.) Использование 9Функции 0225 str или class
расскажут вам, как они хранятся. Если даты или время хранятся как символ или фактор, это означает, что мы не можем вычислить или суммировать прошедшее время.
Для форматирования дат lubridate предоставляет ряд функций, которые представляют собой перестановку букв «m», «d» и «y» для представления порядка месяца, дня и года. Например, если в наших данных есть столбец с датами, такими как 11 мая 1996 года, наши даты упорядочены месяц-день-год. Поэтому мы будем использовать mdy
для преобразования столбца в объект даты. Если бы наши даты были в порядке, скажем, год-месяц-день, мы использовали бы функцию ymd
. lubridate предоставляет функции для каждой перестановки «m», «d», «y».
Давайте продемонстрируем. Ниже мы генерируем два символьных вектора дат, проверяем их класс, переформатируем их с помощью функции mdy
, а затем снова проверяем их класс.
библиотека(смазать) begin <- c("11 мая 1996", "12 сентября 2001", "1 июля 1988") конец <- c("8.07.97","23.10.02","4.01.91") class(begin)
## [1] "character"
class(end)
## [1] "character"
(begin <- mdy(begin))
## [1] "1996 -05-11" "2001-09-12" "1988-07-01"
(конец <- mdy(конец))
## [1] "1997-07-08" "2002-10-23 ""1991-01-04"
класс(начало)
## [1] "Дата"
класс(конец)
## [1] "Дата"
Даты теперь имеют класс "Дата" и печатаются в формате год-месяц-день. При печати они могут казаться символьными данными, но на самом деле это числа. Класс «Дата» означает, что даты хранятся как количество дней с 1 января 19 года.70, с отрицательными значениями для более ранних дат. Мы можем использовать функцию as.numeric
для просмотра необработанных значений.
as.numeric(begin)
## [1] 9627 11577 6756
as. numeric(end)
## [1] 10050 11983 7673
С датами, хранящимися таким образом, мы можем делать такие вещи, как вычитание. для расчета количества дней между двумя датами.
Мы также можем отформатировать даты, содержащие информацию о времени, добавив _h
, _hm
или _hms
к любой из вышеупомянутых функций. «h», «m» и «s» обозначают часы, минуты и секунды соответственно. Ниже мы добавляем некоторые данные о времени к нашим датам и демонстрируем, как использовать mdy_hms
.
begin <- c("11 мая 1996 г., 12:05", "12 сентября 2001 г., 1:00", "1 июля 1988 г., 3:32") end <- c("8.07.97 8:00","23.10.02: 12:00","4.01.91 2:05") (begin <- mdy_hm(begin))
## [1] "1996-05-11 12:05:00 UTC" "2001-09-12 01:00:00 UTC" ## [3] "1988-07-01 03:32:00 UTC"
(end <- mdy_hm(end))
## [1] "1997-07-08 08:00:00 UTC" "2002-10-23 12:00:00 UTC" ## [3] "1991-01-04 02:05:00 UTC"
класс(начало)
## [1] "POSIXct" "POSIXt"
класс(конец)
## [1] "POSIXct" "POSIXt"
Обратите внимание, что класс теперь "POSIXct". «POSIXct» представляет количество секунд с начала 1970 года. Если дата предшествует 1970 году, число секунд отрицательное. Обратите также внимание на то, что к дате и времени добавлены буквы «UTC». UTC — это сокращение от Universal Coordinated Time. Вы можете прочитать больше о UTC здесь, но в основном это стандарт времени, по которому мир регулирует часы. Если мы предпочитаем, мы можем указать часовой пояс при форматировании дат, используя аргумент tz. Вот как мы можем указать восточный часовой пояс в Соединенных Штатах при форматировании наших дат.
begin <- c("11 мая 1996 г., 12:05", "12 сентября 2001 г., 1:00", "1 июля 1988 г., 3:32") end <- c("8.07.97 8:00","23.10.02: 12:00","4.01.91 2:05") (begin <- mdy_hm(begin, tz = "США/Восток"))
## [1] "1996-05-11 12:05:00 EDT" "2001-09-12 01:00:00 EDT" ## [3] "1988-07-01 03:32:00 EDT"
(end <- mdy_hm(end, tz = "США/Восток"))
## [1] "1997-07-08 08:00:00 по восточному поясному времени" "2002-10-23 12:00:00 по восточному поясному времени" ## [3] "1991-01-04 02:05:00 EST"
Обратите внимание, что последняя дата - EST, а не EDT. EST означает «Восточное стандартное время». EDT означает «восточное летнее время». Любой день и время, выпадающие на летнее время, являются EDT. В противном случае это EST. Как узнать, какая фраза о часовом поясе подходит для использования в аргументе tz? Мы можем использовать OlsonNames
функция для просмотра вектора символов всех названий часовых поясов. Просто введите OlsonNames()
в консоли R и нажмите Enter.
Мы также можем читать время без дат, используя функции мс
, чм
или чм
, где снова «ч», «м» и «с» обозначают «часы», «минуты», и «секунды». Вот несколько примеров.
время1 <- c("1:13", "0:58", "1:01") время2 <- c("12:23:11", "09:45:31", "12:05:22") время3 <- c("2:14", "2:16", "3:35") (время1 <- мс(время1))
## [1] "1M 13S" "58S" "1M 1S"
(time2 <- hms(time2))
## [1] "12H 23M 11S" "9H 45M 31S" "12H 5M 22S "
(time3 <- hm(time3))
## [1] "2H 14M 0S" "2H 16M 0S" "3H 35M 0S"
Еще раз, не обманывайтесь распечаткой. Это время на самом деле хранится в секундах. Используйте как.numeric
для проверки.
as.numeric(time1)
## [1] 73 58 61
as.numeric(time2)
## [1] 44591 35131 43522
as.numeric(time3)
## [1] 8040 8160 12900
Класс этих новых объектов времени не является ни «Дата», ни «POSIX», а скорее «Период».
класс(время1)
## [1] "Период" ## атрибут(,"пакет") ## [1] "lubridate"
Период — это один из трех классов, которые lubridate предоставляет для интервалов времени. Давайте узнаем больше об этих классах.
Продолжительность, интервалы и периоды
lubridate предоставляет три класса или три разных способа различать разные типы временных интервалов.
- Продолжительность
- Интервал
- Период
Понимание этих классов поможет вам максимально эффективно использовать смазку.
Самое простое - Длительность. Это просто промежуток времени, измеряемый в секундах. Даты начала нет.
Интервал также измеряется в секундах, но имеет связанную дату начала. Интервал измеряет прошедшие секунды между двумя конкретными моментами времени.
A Period записывает промежуток времени в единицах, превышающих секунды, например, годы или месяцы. В отличие от секунд, годы и месяцы различаются по времени. В июне 30 дней, а в июле 31 день. В феврале 28 дней, за исключением високосных лет, когда их 29.дней. С классом Period мы можем добавить 1 месяц к 1 февраля и получить 1 марта. Это позволяет нам выполнять вычисления в календарном или часовом времени, а не в абсолютном количестве секунд.
Давайте посмотрим на эти три класса в действии. Ниже мы определяем две даты в восточном часовом поясе США. Дата начала — 11 марта 2017 г. в 5:21. Дата окончания – 12 марта 2017 года одновременно. Обратите внимание, что переход на летнее время начинается (или начался, в зависимости от того, когда вы читаете это) 12 марта в 2:00.
start <- mdy_hm("3-11-2017 5:21", tz = "США/Восток") end <- mdy_hm("3-12-2017 5:21", tz = "США/Восток")
Поскольку мы имеем дело с прошедшим временем между двумя датами, давайте начнем с интервалов. Мы можем определить интервал, используя оператор %--%
.
time.interval <- начало %--% конец time.interval
## [1] 2017-03-11 05:21:00 EST--2017-03-12 05:21:00 EDT
Обратите внимание, как печатаются интервалы. Они показывают дату начала и дату окончания. Также обратите внимание, как часовой пояс меняется с EST на EDT, указывая на то, что переход на летнее время начался. Если мы посмотрим на структуру объекта Interval, то увидим, что он содержит прошедшее время в секундах, 82800 и дату начала.
str(time.interval)
## Формальный класс 'Interval' [пакет "lubridate"] с 3 слотами ## ..@ .Данные: число 82800 ## ..@ начало: POSIXct[1:1], формат: "2017-03-11 05:21:00" ## ..@ tzone: chr "US/Eastern"
Чтобы создать длительность между этими двумя датами, мы можем использовать функцию as. duration
.
time.duration <- as.duration(time.interval) time.duration
## [1] "82800s (~23 часа)"
Обратите внимание, что объект Duration печатает прошедшее время в секундах, а также что-то более удобное для чтения, в данном случае часы. Поскольку летнее время вступило в силу в 2 часа ночи во время интервала, час был пропущен. Таким образом, продолжительность между этими двумя моментами времени составляет всего 23 часа.
Если мы посмотрим на структуру объекта Duration, то увидим, что он просто содержит прошедшее время в секундах.
str(time.duration)
## Формальный класс 'Duration' [пакет "lubridate"] с 1 слотом ## ..@ .Data: num 82800
Мы можем создать период из интервала, используя функцию as.period
.
время.период <- как.период(время.интервал) time.period
## [1] "1d 0H 0M 0S"
A Period печатает прошедшее время как целое число в виде лет, месяцев, недель, дней и так далее. Обратите внимание, что этот период составляет 1 день. Хотя технически с даты начала прошло всего 23 часа, по нашим часам прошел один день.
Если мы посмотрим на структуру, то увидим, что Period содержит несколько слотов для значений «часового времени» и, как и объект Duration, не имеет связанной даты.
str(time.period)
## Формальный класс 'Period' [пакет "lubridate"] с 6 слотами ## ..@ .Данные: число 0 ## ..@ год : целое 0 ## ..@ месяц: целое 0 ## ..@ день : целое 1 ## ..@ час : целое 0 ## ..@ minute: int 0
Резюме:
- Интервал — это прошедшее время в секундах между двумя конкретными датами. (Если время не указано, предполагается, что время для каждой даты равно 00:00:00 или полночь.)
- Продолжительность — это прошедшее время в секундах, не зависящее от даты начала.
- A Период — это прошедшее время в «календарном» или «часовом» времени (4 недели, 2 месяца и т. д.), независимо от даты начала.
Расчеты и преобразования
После того, как мы отформатировали даты и определили временной интервал, нам часто нужно выполнить некоторые вычисления и преобразования. Например, мы можем захотеть рассчитать среднее прошедшее время в неделях для разных групп.
Давайте создадим некоторые данные и продемонстрируем. Сначала мы вводим произвольные даты начала и окончания и определяем интервал
start <- c("2012-08-21", "2012-09-01", "2012-08-15", "2012-09-18") end <- c("2012-09-16", "2012-09-06", "2012-08-22", "2012-10-11") elapsed.time <- start %--% end
Если мы просмотрим объект elapsed.time
, мы увидим только диапазоны дат. Мы можем использовать как.duration
или даже как.numeric
для просмотра прошедшего времени в секундах, но в данном случае это не очень полезно. Было бы лучше, если бы мы преобразовали секунды в другую единицу времени, например, в недели или дни. К счастью, смазка упрощает эту задачу.
Хитрость заключается в том, чтобы преобразовать интервалы в длительности, а затем разделить длительность на объект длительности в желаемых единицах измерения. Это многословно, но легко продемонстрировать. Ниже мы покажем, как конвертировать в недели. Сначала мы конвертируем наш интервал в продолжительность, а затем делим на dweeks(1)
. Вызов функции dweeks(1)
генерирует продолжительность одной недели в секундах, что составляет 604800. Разделив это значение на продолжительность, мы получим количество недель.
as.duration(истекшее.время) / dweeks(1)
## [1] 3,7142857 0,7142857 1,0000000 3,2857143
То же самое можно сделать с часами, днями, минутами и годами.
as.duration(истекшее время) / dhours(1)
## [1] 624 120 168 552
as.duration(истекшее время) / ddays(1)
## [1] 26 5 7 23
as.duration(истекшее.время) / dminutes(1)
## [1] 37440 7200 10080 33120
as.duration(истекшее.время)/dyars(1)
## [1] 0,07123288 0,01369863 0,01917808 0,06301370
Как только мы получим длительность в нужных нам единицах, мы можем сделать такие вещи, как найти среднее значение.
mean(as.duration(истекшее.время) / dweeks(1))
## [1] 2.178571
Конечно, это было просто для демонстрации. Всего с 4 значениями среднее значение не очень полезная сводка.
В качестве другого примера рассмотрим следующий вектор символьных данных, суммирующий продолжительность времени. «12w» означает 12 недель, а «4d» — 4 дня.
StudyTime <- c("12w 4d", "11w", "10w 5d", NA, "12w 6d")
Что, если бы мы захотели преобразовать это число в недели? Сначала мы дадим код R, а они объяснят, как он работает.
as.duration(period(StudyTime, Units = c("неделя","день"))) / dweeks(1)
## [1] 12.57143 11.00000 10.71429 NA 12.85714
Сначала мы используем период 5 5 функция для определения периода с использованием наших данных. Аргумент единиц говорит, что первая часть наших данных представляет недели, а вторая часть представляет дни. Затем он преобразуется в объект Duration, в котором хранится время в секундах.