Làm thế nào tôi có thể có `date` đầu ra thời gian từ một múi giờ khác?


115

Tôi có một máy chủ đang chạy với múi giờ được đặt thành UTC. Có vẻ như đó thường là một cách thực hành tốt (vui lòng sửa lại cho tôi nếu tôi sai).

Dù sao đi nữa, một trong những máy chủ tôi kết nối, để scpcác tệp, đang chạy EDTvà lưu trữ các tệp mà tôi cần sao chép ở định dạng/path/to/filename/data20120913

Tôi đã xem xét việc thử rsynccác tệp bằng cách sử dụng -mtime -1cờ như tìm cờ cho các tệp được sửa đổi vào ngày hôm trước, nhưng tôi không gặp may.

Tôi không ngại chỉ sử dụng scpđể sao chép tệp của ngày hiện tại, nhưng hiện tại có một cửa sổ 4 giờ, nơi chạy date +%Y%m%dsẽ cho một ngày khác nhau trên mỗi máy chủ và điều đó làm tôi hơi phiền.

Nhìn qua man datetôi thấy rằng tôi có thể có đầu ra thời gian như UTC, nhưng tôi không thấy cách nào để có đầu ra như một múi giờ khác nhưEDT

Tôi cho rằng tôi cũng có thể sử dụng một cái gì đó như GNUtiện ích mở rộng ngày date -d 20100909 +%sđể lấy ngày tính bằng giây từ epoch, áp dụng 4 * 60 * 60phép tính thứ hai thủ công và xem kết xuất đó là một ngày - nhưng sau đó khi thời gian ban ngày bắt đầu thì nó vẫn còn một giờ nữa. .

Có cách nào đơn giản hơn để xuất ngày ở YYYYMMDDđịnh dạng EDTtrên máy chủ được đặt thành UTCkhông?


EDT không phải là múi giờ được công nhận - ít nhất là trong Linux. Xem "Hãy cẩn thận!" Trả lời dưới đây cho toàn bộ câu chuyện xấu xí. Nếu EDT được nhận dạng trên nhãn hiệu * NIX của bạn, bạn vẫn nên thận trọng và kiểm tra kỹ chuỗi thời gian của mình.
Mike S

Câu trả lời:


175

Do đó, bạn có thể đặt múi giờ cho thời lượng của truy vấn:

TZ=America/New_York date

Lưu ý khoảng trắng giữa TZcài đặt và datelệnh. Trong rcshell giống như Bourne, nó chỉ đặt TZbiến cho dòng lệnh. Trong vỏ khác ( csh, tcsh, fish), bạn luôn có thể sử dụng các envlệnh thay vì:

env TZ=America/New_York date

tl; dr

Trên các hệ thống Linux. múi giờ được xác định trong các tập tin trong /usr/share/zoneinfothư mục. Cấu trúc này thường được gọi là "cơ sở dữ liệu Olson" để tôn vinh người đóng góp sáng lập của nó.

Các quy tắc cho mỗi múi giờ được định nghĩa là các dòng tệp văn bản sau đó được biên dịch thành tệp nhị phân. Các dòng được biên dịch, xác định tên khu vực; một phạm vi dữ liệu và thời gian trong đó khu vực áp dụng; một phần bù từ UTC cho thời gian tiêu chuẩn; và ký hiệu để xác định cách thức chuyển đổi sang và từ thời gian tiết kiệm ánh sáng ban ngày xảy ra, nếu có.

Ví dụ: thư mục "America" ​​chứa thông tin cần thiết cho New York trong tệp America/New_Yorknhư được sử dụng ở trên.

Xin lưu ý rằng đặc điểm kỹ thuật của vùng không tồn tại (tên tệp) bị âm thầm bỏ qua và thời gian UTC được báo cáo. Ví dụ: điều này báo cáo một thời gian không chính xác:

TZ="America/New York" date ### WRONG ###

Đặc tả UNIX đơn, phiên bản-3, được gọi là SUSv3 hoặc POSIX-2001, lưu ý rằng đối với tính di động, chuỗi ký tự xác định mô tả múi giờ nên bắt đầu bằng ký tự dấu hai chấm. Vì vậy, chúng ta cũng có thể viết:

TZ=":America/New_York" date
TZ=":America/Los_Angeles" date

Là một phương pháp thay thế cho đặc tả của các múi giờ bằng cách sử dụng tên đường dẫn đến tệp mô tả, SUSv3 mô tả mô hình POSIX. Trong định dạng này, một chuỗi được định nghĩa là:

std offset [dst[offset][,start-date[/time],end-date[/time]]]

trong đó stdtên thành phần tiêu chuẩn và dstlà tên tiết kiệm ánh sáng ban ngày. Mỗi tên bao gồm ba hoặc nhiều ký tự. Giá trị offsetdương cho các múi giờ ở phía tây kinh tuyến gốc và âm cho các phía đông của kinh tuyến. Phần bù được thêm vào giờ địa phương để lấy UTC (trước đây gọi là GMT). Các trường startendthời gian cho biết khi chuyển đổi tiêu chuẩn / ánh sáng ban ngày xảy ra.

Ví dụ, ở Hoa Kỳ, thời gian tiêu chuẩn sớm hơn UTC 5 giờ và chúng tôi có thể chỉ định EST5EDTthay cho America/New_York. Những lựa chọn thay thế này không phải lúc nào cũng được công nhận, tuy nhiên, đặc biệt là đối với các khu vực bên ngoài Hoa Kỳ và tốt nhất nên tránh.

HP-UX (một UNIX tuân thủ SUSv3) sử dụng các quy tắc văn bản trong /usr/lib/tztabvà các tên POSIX như EST5EDT, CST6CDT, MST7MDT, PST8PDT. Tệp bao gồm tất cả các quy tắc lịch sử cho từng múi giờ, gần giống với cơ sở dữ liệu Olson.

LƯU Ý: Bạn sẽ có thể tìm thấy tất cả các múi giờ bằng cách kiểm tra thư mục sau : /usr/share/zoneinfo.


không chắc là tôi có sai không, nhưng có exportvẻ tốt hơn envlệnh

@JRFerguson - Nếu một múi giờ không được đưa vào danh sách, ví dụ Las Vegas hoặc Nevada, các lựa chọn thay thế trong việc xác nhận thời gian là gì?
động lực

@Motivated Nếu thành phố hoặc tiểu bang của bạn không được bao gồm, hãy chọn một thành phố sử dụng thông tin khu vực giống như của bạn. Chẳng hạn, tôi ở Florida, nơi sử dụng cùng múi giờ với New York, vì vậy máy của tôi đồng bộ hóa với giờ New York.
JRFerguson

1
@JRFerguson - Điều đó giả định rằng người đó biết về các múi giờ khác nhau và có thể sử dụng một phương án khác, ví dụ như New York trong trường hợp của bạn. Đó sẽ là lựa chọn duy nhất? Ví dụ: tôi không sống ở châu Âu và tôi sẽ không biết các múi giờ chồng chéo.
động lực

1
@Motivated Bạn có thể sử dụng một cái gì đó như trang web này để hỗ trợ bạn trong việc tìm kiếm các điểm khác trong khu vực của bạn.
JRFerguson

33

Bạn có thể làm điều này bằng cách thao tác TZbiến môi trường. Sau đây sẽ cung cấp cho bạn thời gian địa phương cho Hoa Kỳ / Đông, cũng sẽ đủ thông minh để xử lý DST khi điều đó xảy ra:

# all on one line
TZ=":US/Eastern" date +%Y%m%d

Tên khu vực xuất phát từ các tập tin và thư mục bên trong /usr/share/zoneinfo.


17

Hãy cẩn thận! Ngày sẽ vui vẻ nhổ hết thời gian trong múi giờ HIỆN TẠI của bạn, nếu bạn cho nó múi giờ thì nó không nhận ra.

Kiểm tra này:

-bash-4.2$ env TZ=EDT date
Wed Feb 18 19:34:41 EDT 2015
-bash-4.2$ date
Wed Feb 18 19:34:43 UTC 2015

Lưu ý rằng không có múi giờ gọi là EDT. Như một vấn đề của thực tế,

-bash-4.2$ find /usr/share/zoneinfo -name "*EDT*"

trả lại

/usr/share/zoneinfo/EST5EDT
/usr/share/zoneinfo/posix/EST5EDT
/usr/share/zoneinfo/right/EST5EDT

Và điều này hoạt động:

-bash-4.2$ TZ=EST5EDT date
Wed Feb 18 14:36:59 EST 2015
-bash-4.2$ date
Wed Feb 18 19:37:01 UTC 2015

Tuy nhiên, nếu bạn của bạn sống ở vùng đất bí ẩn của Gobbledygook và thông tin về khu vực của nó trùng khớp với chính bạn, bạn có thể có ngày đầu ra thời gian trong khu vực của Gobbledygook và sẽ rất vui khi làm như vậy với giá trị thoát để cho bạn biết rằng khu vực này không được biết đến:

-bash-4.2$ TZ=Gobbledygook date
Wed Feb 18 19:37:36 Gobbledygook 2015
-bash-4.2$ echo $?
0

YMMV: trên hộp MacOS / BSD của tôi, TZchuỗi không đúng định dạng trả về thời gian UTC.
Mark Hudson


6

Các ngày Cú pháp là phức tạp và dễ bị lỗi, mà làm cho một dòng lệnh gọi một nỗi đau. Do đó, tôi đã viết một tập lệnh nhỏ (tôi đặt tên là worldtime ), nó sẽ in thời gian (hoặc hiện tại) được chỉ định từ zome thời gian cơ sở (địa phương của bạn) trong một số múi giờ khác và ngược lại.

Nó đây rồi Điều chỉnh nó để phù hợp với nhu cầu của bạn, đưa nó vào đường dẫn của bạn và làm cho nó thực thi được.

#! / thùng / sh
#
# In thời gian được chỉ định (hoặc hiện tại) từ thời gian cơ sở ở các múi giờ khác
# và ngược lại
#

# Múi giờ cơ sở từ / đến mà chuyển đổi
TZBASE = Châu Âu / Athens

# Múi giờ để hiển thị
# Xem / usr / share / areainfo / để biết thêm tên
TZONES = 'UTC America / Los_Angele America / New_York Châu Âu / London Châu Âu / Paris'

# Định dạng hiển thị
FORMAT = '% H:% M (% p)% Z% a% m% b% Y'

nếu ["$ 1"]; sau đó
  thời gian = "$ 1"
khác
  thời gian = `ngày +% T`
fi

# Hiển thị thời gian từ múi giờ đầu vào được chỉ định trong đầu ra được chỉ định
# Múi giờ
lịch chiếu ()
{
  TZIN = $ 1
  TZOUT = $ 2

  TZ = $ TZOUT ngày --date = 'TZ = "' $ TZIN '"' "$ time" + "$ time $ TZIN là $ TZOUT $ FORMAT"
}

cho tz bằng $ TZONES; làm
  lịch chiếu $ TZBASE $ tz
làm xong

tiếng vang

cho tz bằng $ TZONES; làm
  lịch chiếu $ tz $ TZBASE
làm xong


3

Thường thì bạn có dấu thời gian trong múi giờ địa phương và bạn cần chuyển đổi nó sang tz từ xa. Nó có thể được thực hiện với:

TZ=America/Curacao date -d 'Tue Nov 28 00:07:05 MSK 2016'

Ở đâu:

America/Curacao - remote timezone
MSK - local timezone
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.