Ngày xuất hiện


9

Với ba số nguyên không âm y, md(trong đó ít nhất một người phải là số dương) và một ngày hợp lệ với một năm tích cực (trong bất kỳ định dạng hợp lý bao gồm năm, tháng và ngày, và không có thêm thông tin), sản lượng ngày đó là ynăm, mtháng và dngày sau ngày ban đầu.

Lịch Gregorian sẽ được sử dụng cho tất cả các ngày (thậm chí cả ngày trước khi thông qua lịch Gregorian).

Phương pháp tính toán ngày tiếp theo như sau:

  1. Thêm yvào năm
  2. Thêm mvào tháng
  3. Bình thường hóa ngày bằng cách áp dụng Rollover (ví dụ 2018-13-01-> 2019-01-01)
  4. Nếu ngày đã qua ngày cuối cùng của tháng, hãy đổi ngày đó sang ngày cuối cùng trong tháng (ví dụ: 2018-02-30> 2018-02-28)
  5. Thêm dvào ngày
  6. Bình thường hóa ngày bằng cách áp dụng Rollover (ví dụ 2019-01-32-> 2019-02-01)

Năm nhuận (năm chia hết cho 4, nhưng không chia hết cho 100 trừ khi chia hết cho 400) phải được xử lý thích hợp. Tất cả đầu vào và đầu ra sẽ nằm trong phạm vi số nguyên có thể biểu thị của ngôn ngữ của bạn.

Các trường hợp thử nghiệm

Các trường hợp thử nghiệm được cung cấp theo định dạng input => output, trong đó inputmột đối tượng JSON.

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

Bạn có thể sử dụng JSFiddle này để thử nghiệm.

Đây là , vì vậy giải pháp ngắn nhất (trong mỗi ngôn ngữ) sẽ thắng.



2
@LuisfelipeDejesusMunoz Định dạng đầu vào không quan trọng, như tiêu chuẩn ở đây trên PPCG.
Mego

Có bất kỳ hạn chế đến giới hạn trên của y, md(ví dụ có thể dđược 2147483000?)
ErikF

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

1
Còn định dạng đầu ra thì sao? Chúng ta có thể xuất một đối tượng ngày không? Chúng ta có thể lấy một đối tượng ngày?
Asone Tuhid

Câu trả lời:


3

C (gcc) , 291 byte

Điều này khá thú vị khi nhận được các giá trị giống như nội dung 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]++;}

Hãy thử trực tuyến!

Chưa chơi gôn:

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

Hãy thử trực tuyến!



1

perl -MDate :: Calc =: all -E, 28 byte

$,=$";say Add_Delta_YMD@ARGV

Điều này có 6 đối số: năm đầu vào, tháng và ngày (dưới dạng đối số riêng biệt) và số năm, tháng và ngày để thêm.


2
Điều này không giải quyết "quy tắc 4" kỳ quặc của nhiệm vụ, do đó, một số trường hợp thử nghiệm thất bại - ví dụ, perl -MDate::Calc=:all -E '$,=$";say Add_Delta_YMD@ARGV' -- 2000 2 29 1 0 0trả về 2001 3 1thay vì 2001 2 28như OP mong đợi (trường hợp thử nghiệm 6).
- Phục hồi Monica

1

R , 88 byte

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}

Hãy thử trực tuyến!

Hàm lấy 3 đối số ( Y,M,D) cho ngày và 3 đối số khác ( y,m,d) cho các giá trị được thêm vào.

Sản lượng đi kèm với được thêm vào trước 12:00:00 GMTđó là định dạng mặc định cho ISOdate's


1

Perl 6 ,  60 50 45  44 byte

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

Kiểm tra nó (60)
Đầu vào là( "2000-02-29", year => 1, month => 0, day => 0 )


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

Kiểm tra nó (50)
Đầu vào là( Date.new("2000-02-29"), year => 1, month => 0, day => 0 )


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

Kiểm tra nó (45)
Đầu vào là ( Date.new("2000-02-29"), %( year => 1 ) )
(Không cần bao gồm các khóa có giá trị 0)


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

Kiểm tra nó (44)
Đầu vào là( Date.new("2000-02-29"), year => 1 )

Mở rộng:

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

Bạn có thể xóa khoảng trống trướcfor
Jo King


1

Java 8, 51 byte

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

Đầu vào ( s) và đầu ra đều java.time.LocalDate.

Hãy thử trực tuyến.

Giải trình:

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

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

Sử dụng lubridategói. Các %m+%nhà điều hành ghi là đường cho add_with_rollbackchức năng mà chủ yếu thực hiện những gì các câu hỏi yêu cầu.

TIO không có lubridate, do đó bạn có thể Hãy thử nó ở đây Thay vào đó với f <-thêm vào phía trước hàm trên cùng với trường hợp kiểm tra:

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

Bạn có thể lưu lưu hai byte với: function(x,y)x%m+%period(y,c("ye","mo","d")) require(lubridate)(yêu cầu hết chức năng)
JayCe

0

Bash , 150 149 byte

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

Hãy thử trực tuyến!

Đưa đầu vào qua các đối số dòng lệnh theo thứ tự: năm cũ, tháng cũ, ngày cũ. thay đổi năm, thay đổi tháng, thay đổi ngày. Xuất ra một chuỗi như Wed Feb 28 00:00:00 UTC 2018stdout.


0

PHP , 203 byte

<?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');

Để chạy nó:

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

Thí dụ:

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

Hoặc dùng thử trực tuyến!

Kiểm tra: Hãy thử trực tuyến!


0

T-SQL, 53 byte

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

Tôi không chắc chắn rằng nó có vấn đề, nhưng tôi đang áp dụng điều chỉnh Năm, tiếp theo là điều chỉnh Tháng, sau đó là Ngày. Tất cả các giá trị kiểm tra kiểm tra.

Theo tiêu chuẩn IO của chúng tôi , đầu vào được lấy từ bảng t có sẵn với trường ngày a và các trường nguyên y , md .

Lưu ý một cách thú vị rằng không phải viết hoa là vấn đề giữa mã loại ngày ( D , MY ) và các giá trị đầu vào của tôi ( d , my ) đơn giản là thứ tự của các tham số trong DATEADDhàm SQL .


1
Điều này có vượt qua bài kiểm tra 6 không? Vì nó không thực hiện Quy tắc 4, tôi nghĩ rằng nó sẽ đưa ra 2001 3 1thay vì 2001 2 28cho đầu vào 6.
- Phục hồi lại

@sundar Hình như bạn đúng; Tôi nghĩ rằng tôi đã vượt qua tất cả các trường hợp thử nghiệm. Tôi sẽ xem liệu nó có thể được sửa chữa không ...
BradC
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.