発生日


9

3つの非負の整数を考えるとym、およびd(うち少なくとも一つが正でなければならない)と正の年と有効な日付(年、月、日を含む任意の合理的な形式であり、追加情報なし)、出力元の日付からy年、m月、d日後の日付。

グレゴリオ暦はすべての日付に使用されます(グレゴリオ暦の採用前の日付も含みます)。

次の日付の計算方法は次のとおりです。

  1. 追加y年に
  2. m月に追加
  3. ロールオーバーを適用して日付を正規化(例:2018-13-01-> 2019-01-01
  4. 日が月の最終日を過ぎている場合は、月の最終日に変更します(例2018-02-30-> 2018-02-28)。
  5. d日に追加
  6. ロールオーバーを適用して日付を正規化(例:2019-01-32-> 2019-02-01

うるう年(4で割り切れる年。ただし、400で割り切れる場合を除き、100で割り切れない年)は、適切に処理する必要があります。すべての入力と出力は、言語の表現可能な整数の範囲内にあります。

テストケース

テストケースは、JSONオブジェクトの形式input => outputで提供されinputます。

{"date":"2018-01-01","add":{"d":1}} => 2018-01-02
{"date":"2018-01-01","add":{"M":1}} => 2018-02-01
{"date":"2018-01-01","add":{"Y":1}} => 2019-01-01
{"date":"2018-01-30","add":{"M":1}} => 2018-02-28
{"date":"2018-01-30","add":{"M":2}} => 2018-03-30
{"date":"2000-02-29","add":{"Y":1}} => 2001-02-28
{"date":"2000-02-29","add":{"Y":4}} => 2004-02-29
{"date":"2000-01-30","add":{"d":2}} => 2000-02-01
{"date":"2018-01-01","add":{"Y":2,"M":3,"d":4}} => 2020-04-05
{"date":"2018-01-01","add":{"Y":5,"M":15,"d":40}} => 2024-05-11

このJSFiddleをテストに使用できます。

これはなので、(各言語で)最短のソリューションが優先されます。



2
@LuisfelipeDejesusMunoz PPCGの標準であるように、入力形式は重要ではありません。
Mego

上限に制限はありますymそしてd(例えば、可能性がd2147483000も?)
ErikF

@ErikFAll inputs and outputs will be within the representable integer range of your language.
Mego

1
出力フォーマットについてはどうですか?日付オブジェクトを出力できますか?日付オブジェクトを取得できますか?
Asone Tuhid

回答:


3

C(gcc)、291バイト

これは、組み込みのJSと同じ値を返すのがとても楽しいです。

z,m=0xEEFBB3;int*y;g(){z=28+(m>>y[1]*2&3)+!(y[1]-1)*(!(*y%4)&&(*y%100)||!(*y%400));}h(a){z=(a>g())?g():a;}j(){*y+=y[1]/12;y[1]%=12;y[2]=h(y[2]);}f(int*a){y=a+6;for(z=0;z<3;z++)y[z]=a[z];y[1]--;j();*y+=a[3];y[1]+=a[4];j();y[2]+=a[5];for(;y[2]>h(y[2]);(y[1]=++y[1]%12)||++*y)y[2]-=g();y[1]++;}

オンラインでお試しください!

ゴルフなし:

// De No Oc Se Au Jl Jn Ma Ap Mr Fe Ja
// 31 30 31 30 31 31 30 31 30 31 28 31 = Month length
// 11 10 11 10 11 11 10 11 10 11 00 11 = Offset (2-bit representation)
//   E     E     F     B     B     3   = Hex representation

int m=0xEEFBB3; // Month lengths-28 in reverse order, stored as 2 bits/month
int *y; // Pointer to the output date, shared as a global between calls

// Regenerate month length and add leap day
int days_month(void) { 
  return 28+(m>>y[1]*2&3)+!(y[1]-1)*(!(*y%4)&&(*y%100)||!(*y%400));
}

int calendar_day(int day) { return day>days_month()?days_month():day; }

void truncate_date(void) {
  *y+=y[1]/12; y[1]%=12;
  y[2]=calendar_day(y[2]);
}

void f(int *a) {
  int z;
  y=a+6;
  for(z=0;z<3;z++)y[z]=a[z];y[1]--; // Convert month to 0-based
  truncate_date();
  *y+=a[3]; y[1]+=a[4]; truncate_date();
  y[2]+=a[5];
  for(;y[2]>calendar_day(y[2]);(y[1]=++y[1]%12)||++*y)
    y[2]-=days_month();
  y[1]++; // Return month to 1-based
}

オンラインでお試しください!



1

perl -MDate :: Calc =:all -E、28バイト

$,=$";say Add_Delta_YMD@ARGV

これは6つの引数を取ります。入力の年、月、日付(個別の引数として)、および追加する年、月、日数です。


2
例えばのために、 -これは、タスクの風変わりな「規則4」を扱っていないので、テストケースの一部を失敗した。perl -MDate::Calc=:all -E '$,=$";say Add_Delta_YMD@ARGV' -- 2000 2 29 1 0 0リターン2001 3 1の代わりに、2001 2 28OPのを期待(テストケース6)として。
sundar-モニカを

1

R、88バイト

function(Y,M,D,y,m,d,o=M+m){while(is.na(x<-ISOdate(Y+y+o%/%12,o%%12,D)))D=D-1;x+864e2*d}

オンラインでお試しください!

Y,M,D日付に3つの引数(y,m,d)、追加する値に他の3つの引数()を取る関数。

先頭に付加して出力が来る12:00:00 GMTのデフォルトのフォーマットであるISOdate


1

Perl 6の 60の50 45  44バイト

{Date.new($^a).later(:$:year).later(:$:month).later(:$:day)}

テストする(60)
入力は( "2000-02-29", year => 1, month => 0, day => 0 )


{$^a.later(:$:year).later(:$:month).later(:$:day)}

テスト(50)
入力は( Date.new("2000-02-29"), year => 1, month => 0, day => 0 )


{$/=$^a;$/.=later(|$_) for |[R,] $^b.sort;$/}

テストする(45)
入力は( Date.new("2000-02-29"), %( year => 1 ) )
(値0のキーを含める必要はありません)


{$/=$^a;$/.=later(|$_) for |[R,] %_.sort;$/}

テストする(44)
入力は( Date.new("2000-02-29"), year => 1 )

拡張:

{  # bare block lambda

  $/ = $^a; # store only positional param into a modifiable scalar
            # (params are readonly by default)


  # do a loop over the data to add

  $/ .= later(    # add using Date.later()
    |$_           # turn current iterated Pair into a named parameter
  )

    for

      |           # flatten so that `for` will iterate

        [R,]      # shorter than `reverse` (year=>1, month=>0, day=>0)

          %_.sort # sort the named arguments (day=>0, month=>0, year=>1)
  ;

  # return new Date
  $/
}

前のスペースは削除できますfor
Jo King


1

Java 8、51バイト

(s,y,m,d)->s.plusYears(y).plusMonths(m).plusDays(d)

入力(s)と出力の両方java.time.LocalDateです。

オンラインでお試しください。

説明:

(s,y,m,d)->        // Method with LocalDate and 3 int parameters and LocalDate return-type
  s.plusYears(y)   //  Add the years to the input start-Date
   .plusMonths(m)  //  Add the months as well
   .plusDays(d)    //  And add the days as well

1

R、65バイト

function(x,y){require(lubridate)
x%m+%period(y,c("ye","mo","d"))}

lubridateパッケージを使用します。%m+%中置演算子は砂糖であるadd_with_rollback基本的に質問が求めてき実装する関数。

TIOにはないlubridateので、上記の関数の前にテストケースを追加して、ここで試すことができますf <-

f(as.Date("2018-01-01"),c(0,0,1))
f(as.Date("2018-01-01"),c(0,1,0))
f(as.Date("2018-01-01"),c(1,0,0))
f(as.Date("2018-01-30"),c(0,1,0))
f(as.Date("2018-01-30"),c(0,2,0))
f(as.Date("2000-02-29"),c(1,0,0))
f(as.Date("2000-02-29"),c(4,0,0))
f(as.Date("2000-01-30"),c(0,0,2))
f(as.Date("2018-01-01"),c(2,3,4))
f(as.Date("2018-01-01"),c(5,15,40))

あなたは、2つのバイト保存するには、保存することができますfunction(x,y)x%m+%period(y,c("ye","mo","d")) require(lubridate)(機能のoutisde必要)
JayCe

0

バッシュ150 149バイト

a=$2+$5-1+b
y=$1+$4+a/12
m=1+a%12
d=date
$d -d@$[$($d +%s+$6*86400 -d$[y]-$[m]-$($d +$3%n%d -d@$[`b=1;$d +%s-86400 -d$[y]-$[m]-1`]|sort -n|head -1))]

オンラインでお試しください!

コマンドライン引数を介して、古い年、古い月、古い日の順に入力を受け取ります。年の変更、月の変更、日の変更。Wed Feb 28 00:00:00 UTC 2018stdoutのような文字列を出力します。



0

T-SQL、53バイト

SELECT DATEADD(D,d,DATEADD(M,m,DATEADD(Y,y,a)))FROM t

それが重要かどうかはわかりませんが、年の調整、月の調整、日の順で適用しています。すべてのテスト値がチェックアウトされます。

私たちのIO標準に従って、入力は日付フィールドaと整数フィールドym、およびdを持つ既存のテーブルtから取得されます。

興味深いことに、日付タイプコードDM、およびY)と入力値dm、およびy)の間で重要なのは大文字ではなく、SQL DATEADD関数のパラメーターの順序だけです。


1
これはテストケース6に合格しますか?それがルール4を実装していないので、私はそれを与えると思う2001 3 1の代わりを2001 2 28入力6.ために
サンダー-復活モニカ

@sundar正しいようです。私はすべてのテストケースに合格したと思いました。修正できるかどうか確認します...
BradC、2018
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.