Tarih Oluşumları


9

Üç negatif olmayan tamsayılar Verilen y, mve d(bunlardan en az biri pozitif olmalıdır) ve pozitif yıl geçerli bir tarih (yıl, ay ve günü içeren herhangi makul bir biçimde ve hiçbir ek bilgi), çıkış olduğu tarih yyıl, may ve dalındığı tarihten itibaren gün.

Gregoryen takvimi tüm tarihler için kullanılmalıdır (Gregoryen takviminin kabul edilmesinden önceki tarihler bile).

Bir sonraki tarihi hesaplama yöntemi aşağıdaki gibidir:

  1. yYıla ekle
  2. mAya ekle
  3. Rollovers uygulayarak tarihi normalleştirin (ör. 2018-13-01-> 2019-01-01)
  4. Gün ayın son gününü geçtiyse, ayın son gününe değiştirin (örn. 2018-02-30-> 2018-02-28)
  5. dGüne ekle
  6. Rollovers uygulayarak tarihi normalleştirin (ör. 2019-01-32-> 2019-02-01)

Artık yıllar (4 ile bölünebilir, ancak 400 ile bölünemezse 100'e bölünemez) uygun şekilde ele alınmalıdır. Tüm girişler ve çıkışlar dilinizin temsil edilebilir tamsayı aralığında olacaktır.

Test Durumları

Test durumlarda biçiminde sağlanır input => output, inputbir JSON nesnesidir.

{"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

Bu JSFiddle'ı test etmek için kullanabilirsiniz .

Bu Böylece, en kısa çözüm (her dilde) kazanır.


Sandbox post (silindi)
Mego

2
@LuisfelipeDejesusMunoz Giriş biçimi, PPCG'deki norm gibi önemli değildir.
Mego

Üst sınırları için herhangi bir kısıtlama var mıdır y, mve d(örn olabilir d2147483000 olmak?)
ErikF

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

1
Çıktı formatları ne olacak? Bir tarih nesnesi çıktısı alabilir miyiz? Bir tarih nesnesi alabilir miyiz?
Asone Tuhid

Yanıtlar:


3

C (gcc) , 291 bayt

Bu, JS yerleşikiyle aynı değerleri döndürmek için oldukça eğlenceliydi.

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]++;}

Çevrimiçi deneyin!

Un-golfed:

// 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
}

Çevrimiçi deneyin!



1

perl -MDate :: Calc =: tümü -E, 28 bayt

$,=$";say Add_Delta_YMD@ARGV

Bu 6 argüman alır: giriş yılı, ay ve tarih (ayrı bağımsız değişkenler olarak) ve eklenecek yıl, ay ve gün sayısı.


2
Bu yüzden test durumları bazı başarısız, İlginç görevin "kuralı 4" ile uğraşmaz -. Örn için, perl -MDate::Calc=:all -E '$,=$";say Add_Delta_YMD@ARGV' -- 2000 2 29 1 0 0döner 2001 3 1yerine 2001 2 28OP beklentiden (test durumu 6) olarak.
sundar - Monica'yı eski haline

1

R , 88 bayt

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}

Çevrimiçi deneyin!

Y,M,DTarih için 3 argüman ( y,m,d) ve eklenecek değerler için diğer 3 argüman ( ) alan bir işlev .

Çıktı 12:00:00 GMT, ISOdate's için varsayılan biçim olan önceden eklenmiş olarak gelir


1

Perl 6 ,  60 50 45  44 bayt

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

Test edin (60)
Giriş( "2000-02-29", year => 1, month => 0, day => 0 )


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

Test edin (50)
Giriş( Date.new("2000-02-29"), year => 1, month => 0, day => 0 )


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

Test et (45)
Giriş ( Date.new("2000-02-29"), %( year => 1 ) )
(0 değerine sahip anahtarlar eklemenize gerek yok)


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

Test edin (44)
Giriş( Date.new("2000-02-29"), year => 1 )

Expanded:

{  # 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
  $/
}

Daha önce alanı kaldırabilirsinizfor
Jo King


1

Java 8, 51 bayt

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

Girdi ( s) ve çıktının ikisi de java.time.LocalDate.

Çevrimiçi deneyin.

Açıklama:

(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 bayt

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

lubridatePaketi kullanır . %m+%İnfix operatörü için şeker add_with_rollbackesasen soru sorar neyi uygulayan fonksiyonu.

TIO yok lubridatesen böylece yerine İşte Deneyin ile f <-test durumlarda birlikte yukarıda işlevine de başa:

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))

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

0

Bash , 150 149 bayt

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))]

Çevrimiçi deneyin!

Komut satırı bağımsız değişkenleri aracılığıyla sırayla girdi alır: eski yıl, eski ay, eski gün. yıl, ay, gün. Stdout benzeri bir dize çıktılar Wed Feb 28 00:00:00 UTC 2018.


0

PHP , 203 bayt

<?list(,$a,$y,$m,$d)=$argv;$b=new DateTime($a);$j=$b->format('j');$b->modify("+$y year +$m month");$j==$b->format('j')?:$b->modify('last day of last month');$b->modify("+$d day");echo$b->format('Y-m-d');

Çalıştırmak için:

php -n <filename> <date> <y> <m> <d>

Misal:

php -n date_occurrences.php 2018-01-01 5 15 40

Veya çevrimiçi deneyin!

Testler: Çevrimiçi deneyin!


0

T-SQL, 53 Bayt

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

Önemli olduğundan emin değilim, ancak Yıl düzenlemesini, ardından Ay düzenlemesini ve ardından Gün'ü uyguluyorum. Tüm test değerleri kontrol edilir.

ES standartlarımıza göre , tarih alanı a ve y , m ve d tamsayı alanlarıyla önceden var olan bir tablodan t alınır .

İlginçtir ki, tarih tipi kodları ( D , M ve Y ) ve girdi değerlerim ( d , m ve y ) arasında önemli olan büyük harf kullanımı değildir, bu sadece SQL DATEADDişlevindeki parametrelerin sırasıdır .


1
Bu test örneği 6'yı geçiyor mu? Kural 4'ü uygulamadığından, girdi 6 2001 3 1yerine vereceğini düşünüyorum 2001 2 28.
sundar - Monica'yı eski haline

@sundar Doğru gibi görünüyorsunuz; Tüm test vakalarını geçtiğimi sanıyordum. Düzeltilip düzeltilemeyeceğini
göreceğim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.