2017-05-26 6 views
0

気候モデルの出力を集めて作業しています(具体的にCMIP5 models)。これらはタイムスタンプの温度、風などのnetcdfsです。グレゴリオ暦以外のカレンダーを使用してエポックから変換する

これらはすべてUTCでdays since YYYY-mm-dd 00:00:00の規約を使用しています。私はlubridateを使用して簡単に日付(ない日時)オブジェクトに変換されてきた:

library(tidyverse) 
input$date.utc = 
    ymd_hms('0001-01-01 00:00:00', tz = 'UTC') + 
    days(floor(input$time)) 

私は2つの問題をヒットしました。一つは、各モデルが異なる時代を持っているということです。それは簡単に修正できます。もう1つ、厳しい、問題は、すべてのモデルがグレゴリオ暦を使用しているというわけではありません。あるものは、うるう年がない365日間のバリエーションを使用します。

lubridate機能では、グレゴリオ暦以外のカレンダーを指定する方法はありません。これは可能ですか?

答えて

0

私はlubridateでこの機能を見つけることができなかったので、私は、少なくとも日付のベクトルの各要素と与えられたエポック間のうるう日の数を計算する機能を書いた:これにより

# count_leap_days: returns an integer for the number of leap days between a 
# supplied vector of dates and a fixed epoch 
count_leap_days <- function(dates, epoch = ymd('1850-01-01'), proleptic = FALSE) 
{ 
    require(lubridate) 

    # check input 
    if (!is(epoch, 'Date') | !is(dates, 'Date')) 
    { 
    stop('count_leap_days: both arguments must be Date objects.') 
    } 
    if (any(dates <= epoch)) 
    { 
    stop('count_leap_days: dates should all be later than epoch.') 
    } 
    if (proleptic = FALSE & epoch < ymd('1582-10-15')) 
    { 
    message('count_leap_days: ', 
     'no leap days before 1582-10-15 unless proleptic = TRUE.') 
    epoch = ymd('1582-10-15') 
    } 

    # get the year range 
    # exclude start (end) years if they begin after (start before) feb 29 
    y.epoch = year(epoch) + 
    ifelse(epoch >= ymd(paste0(year(epoch), '-03-01')), 1, 0) 
    y.dates = year(dates) - 
    ifelse(dates <= ymd(paste0(year(dates), '-02-28')), 1, 0) 
    span = y.dates - y.epoch + 1 

    # a year is a leap year if it's: 
    # - divisble by 4. but 
    # - NOT if it's also divisible by 100, unless 
    # - it's also divisible by 400. 
    # all years div. by 4 are also div. by 100, and 
    # all years div. by 100 are also div. by 400. 
    # hence, total days = (div. by 4) - (div. by 100) + (div. by 400) 
    div4 = span %/% 4 + 
    ifelse(
     (y.epoch %% 4) %in% c(0, (4 - (span %% 4) - 1):(4 - 1)) & 
     (y.dates %% 4) %in% 0:(span %% 4 - 1), 
    1, 0) 
    div100 = span %/% 100 + 
    ifelse(
     (y.epoch %% 100) %in% c(0, (100 - (span %% 100) - 1):(100 - 1)) & 
     (y.dates %% 100) %in% 0:(span %% 100 - 1), 
    1, 0) 
    div400 = span %/% 400 + 
    ifelse(
     (y.epoch %% 400) %in% c(0, (400 - (span %% 400) - 1):(400 - 1)) & 
     (y.dates %% 400) %in% 0:(span %% 400 - 1), 
    1, 0) 
    return(div4 - div100 + div400) 
} 

私は365日のカレンダーからグレゴリオ暦に変換することができます。逃した閏日の数を追加するだけです:

input$date.utc = input$date.utc + 
    count_leap_days(input$date.utc, epoch = epoch) 
関連する問題