In thời gian hiện tại, mất vài giây để nhảy vào tài khoản


9

(Lưu ý: mặc dù có liên quan, thử thách này không phải là bản sao của thử thách này vì nó yêu cầu tự động xác định giây nhuận thay vì mã hóa thời gian của chúng và không phải là bản sao của thử thách này vì phần lớn khó khăn đến từ việc xác định thời gian mà không có bước nhảy vọt thứ hai , một cái gì đó mà hầu hết các API thời gian không làm theo mặc định. Như vậy, một giải pháp có thể trông khác với một giải pháp cho một trong những thách thức đó.)

Chúng ta sẽ đến cuối năm 2016, nhưng sẽ mất nhiều thời gian hơn mọi người mong đợi. Vì vậy, đây là một thách thức kỷ niệm thêm thứ hai của chúng tôi trong năm nay.

Xuất thời gian hiện tại trong UTC, dưới dạng giờ, phút, giây. (Ví dụ: các định dạng đầu ra hợp pháp cho giữa trưa sẽ bao gồm 12:00:00[12,0,0]; định dạng không quá quan trọng ở đây.)

Tuy nhiên, có một điểm mấu chốt: chương trình của bạn phải xử lý các bước nhảy vọt một cách thích hợp, cả quá khứ và tương lai. Điều này có nghĩa là chương trình của bạn sẽ phải có được một danh sách các giây nhuận từ một số nguồn trực tuyến hoặc cập nhật / cập nhật tự động. Bạn có thể kết nối với Internet để có được điều này nếu bạn muốn. Tuy nhiên, bạn chỉ có thể kết nối với một URL trước thử thách này (tức là không tải xuống các phần của chương trình từ nơi khác) và bạn không được sử dụng kết nối để xác định thời gian hiện tại (cụ thể: chương trình của bạn phải hoạt động ngay cả khi có bất kỳ nỗ lực truy cập nào Internet trả về một trang dài tới 24 giờ).

Các API mặc định của hầu hết các hệ điều hành cho thời điểm hiện tại sẽ làm lệch thời gian xung quanh các giây nhuận để ẩn chúng khỏi các chương trình có thể bị nhầm lẫn. Như vậy, khó khăn chính của thử thách này là tìm ra một phương thức hoặc API để hoàn tác điều đó và tìm ra thời gian hiện tại chưa được sửa đổi thực sự trong UTC.

Về lý thuyết, chương trình của bạn phải hoàn toàn chính xác nếu nó chạy trên một máy tính cực kỳ nhanh và không được cố tình mất quá nhiều thời gian để chạy. (Tất nhiên, trong thực tế, chương trình của bạn sẽ chạy trên một máy tính không hoàn hảo và do đó có thể sẽ không chạy ngay lập tức. Bạn không phải lo lắng về việc làm mất hiệu lực kết quả này, nhưng không được phụ thuộc vào tính chính xác của chương trình. )

Chương trình của bạn phải hoạt động bất kể múi giờ hệ thống được đặt thành. (Tuy nhiên, nó có thể yêu cầu thông tin từ hệ điều hành hoặc môi trường về múi giờ nào đang được sử dụng và có thể cho rằng câu trả lời là chính xác.)

Là một , chương trình ngắn nhất sẽ thắng. Chúc may mắn!


Câu trả lời:


2

PowerShell , 161 byte

(('{0:H:m:s}','23:59:60')[(($d=[datetime]::UtcNow).Ticks-6114960*98e9)/1e8-in((irm ietf.org/timezones/data/leap-seconds.list)-split'[^@]	|
'-match'^\d{9}')])-f$d

Hãy thử trực tuyến! (không hoạt động ở đây, có vẻ như TIO không nhận ra irmiwrcó thể đó là một tính năng bảo mật?)

Kiểm tra logic (Ngày mã hóa):

(('{0:H:m:s}','23:59:60')[(($d=[datetime]'1/1/2017 00:00:00').Ticks-6114960*98e9)/1e8-in((irm ietf.org/timezones/data/leap-seconds.list)-split'[^@]	|
'-match'^\d{9}')])-f$d

Ghi chú

Có một TABngắt dòng theo nghĩa đen và nghĩa đen ( 0xA) trong chuỗi regex, do đó tôi không phải thoát chúng (lưu 1 byte mỗi chuỗi).

Giải trình

Thời gian đã cho (của giây nhuận) trong tệp ietf là tính bằng giây kể từ NTP epoch 1/1/1900 00:00:00. Trên Windows, "tick" chỉ đơn giản là một phần mười triệu giây (10.000.000 tick / giây).

Nếu bạn thêm một số nguyên vào [datetime]nó, nó sẽ tính giá trị số nguyên là tick, vì vậy tôi đang sử dụng giá trị đánh dấu được mã hóa cứng của NTP epoch, sau đó trừ nó khỏi giá trị đánh dấu của thời gian UTC hiện tại (giá trị ban đầu được gán đồng thời đến $d).

Để làm cho giá trị đánh dấu mã hóa cứng đó nhỏ hơn, tôi lấy đi một số không (9 trong số chúng) và chia cho 98, sau đó nhân với 98e9(98 * 10 9 ).

Kết quả của phép trừ đó là giá trị tính theo tích tắc kể từ NTP epoch. Điều đó được chia cho 1e8(không 1e9, vì những lý do sẽ rõ ràng trong giây lát) để có được giá trị tính bằng giây (sắp xếp) kể từ NTP epoch. Nó sẽ nhỏ hơn theo hệ số 10, thực sự.

Lấy tài liệu từ IETF, thay vì chia nó thành các dòng trước, sau đó xử lý các dòng bằng dấu thời gian, tôi quyết định tách cả hai dấu ngắt dòng và trên các TABký tự, vì đó là những gì xuất hiện sau dấu thời gian. Do một dòng sai lầm duy nhất trong tệp, một mình nó sẽ bao gồm một dấu thời gian bổ sung mà chúng tôi không muốn. Dòng này trông như thế này:

#@	3707596800

Vì vậy, tôi đã thay đổi regex để phân tách [^@]\t(bất kỳ ký tự nào không được @theo sau bởi a TAB) hoạt động để loại trừ dòng đó, nhưng cuối cùng cũng tiêu thụ cuối cùng 0trong mỗi dấu thời gian.

Đó là lý do tại sao tôi chia 1e8và không 1e9, để giải thích cho sự mất tích 0.

Dấu thời gian hiện tại được kiểm tra để xem nó tồn tại trong danh sách các dấu thời gian thứ hai bước nhảy vọt. Toàn bộ quá trình tôi mô tả là bên trong bộ truy cập mảng [], vì vậy [bool]giá trị kết quả được kết hợp thành một 0( $false) hoặc 1( $true). Mảng chúng tôi lập chỉ mục chứa hai phần tử: chuỗi định dạng để hiển thị thời gian và mã hóa cứng 23:59:60. Tính trung thực của so sánh đã nói ở trên sẽ xác định cái nào sẽ được chọn và được đưa vào toán tử định dạng -fvới ngày hiện tại được gán trước đó $dlàm tham số.


Điều này in cái thứ hai sau một giây nhảy vọt? Tôi có thể theo logic trong vài giây, nhưng không chắc tôi có thể theo logic nhiều lần không. (Windows có tự nhiên hiển thị cả giây nhảy vọt và giây tiếp theo là 00:00:00 không?)

@ ais523 nó sẽ hiển thị lần thứ hai sau bước nhảy vọt thứ hai như bất kể thời gian hệ thống là gì. Windows không biết về giây nhuận, vì vậy đồng hồ sẽ nhanh 1 giây cho đến khi được sửa bằng cài đặt đồng bộ hoặc thủ công. Đưa ra các yêu cầu tôi thực sự không thể điều chỉnh cho điều đó, vì không thể xác định liệu thời gian hệ thống có chính xác hay không mà không sử dụng nguồn thời gian bên ngoài bị cấm. Về điều tốt nhất tôi có thể làm là thêm mã vào điều này buộc đồng bộ hóa NTP sau khi nó đã in thời gian, điều này tất nhiên có thể thất bại (lỗi mạng, không đặt nguồn thời gian, v.v.), nếu điều đó thậm chí còn được cho phép.
nghĩa tự do
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.