2017-01-18 40 views
1

在Linux上使用的Bash shell,並給出一個日期時間,我怎麼能確定有多少時間上有那一天的小時數?巴什 - 在給定的一天

日期時間涉及一些時區與夏令,例如MET。

+1

你需要知道的是什麼時候?就像'date'命令一樣? –

+0

你在問什麼?如果某一天有23,24或25小時? – Jdamian

+0

@Jdamian:的確,我需要知道它是否是23,24或25小時 –

回答

1

爲了完全解釋所有的場景,你需要考慮幾件事情:

  • 並不是每一個地方一天有一個午夜,如果你傳遞一個日期上的一個date命令將失敗這些天,除非你也傳遞一個時間和UTC的偏移量。這主要發生在春季轉型日。例如:

    $ TZ=America/Sao_Paulo date -d '2016-10-16' 
    date: invalid date '2016-10-16' 
    
  • 並非每個DST過渡都是1小時。 America/Lord_Howe切換30分鐘。 Bash只執行整數除法,所以如果你想要小數,你必須使用one of these techniques

這裏是佔了這些功能:

seconds_in_day() { 
    # Copy input date to local variable 
    date=$1 

    # Start with the offset at noon on the given date. 
    # Noon will almost always exist (except Samoa on 2011-12-30) 
    offset1=$(date -d "$date 12:00" +%z) 

    # Next get the offset for midnight. If it doesn't exist, the time will jump back to 23:00 and we'll get a different offset. 
    offset1=$(date -d "$date 00:00 $offset1" +%z) 

    # Next get the offset for the next day at midnight. Again, if it doesn't exist, it will jump back an hour. 
    offset2=$(date -d "$date 00:00 $offset1 + 1 day" +%z) 

    # Get the unix timestamps for both the current date and the next one, at midnight with their respective offsets. 
    unixtime1=$(date -d "$date 00:00 $offset1" +%s) 
    unixtime2=$(date -d "$date 00:00 $offset2 + 1 day" +%s) 

    # Calculate the difference in seconds and hours. Use awk for decimal math. 
    seconds=$((unixtime2 - unixtime1)) 
    hours=$(awk -v seconds=$seconds 'BEGIN { print seconds/3600 }') 

    # Print the output 
    echo "$date had $seconds secs in $TZ, or $hours hours." 
} 

例子:

$ TZ=America/Los_Angeles seconds_in_day 2016-03-12 
2016-03-12 had 86400 secs in America/Los_Angeles, or 24 hours. 
$ TZ=America/Los_Angeles seconds_in_day 2016-03-13 
2016-03-13 had 82800 secs in America/Los_Angeles, or 23 hours. 
$ TZ=America/Los_Angeles seconds_in_day 2016-03-14 
2016-03-14 had 86400 secs in America/Los_Angeles, or 24 hours. 

$ TZ=America/Los_Angeles seconds_in_day 2016-11-05 
2016-11-05 had 86400 secs in America/Los_Angeles, or 24 hours. 
$ TZ=America/Los_Angeles seconds_in_day 2016-11-06 
2016-11-06 had 90000 secs in America/Los_Angeles, or 25 hours. 
$ TZ=America/Los_Angeles seconds_in_day 2016-11-07 
2016-11-07 had 86400 secs in America/Los_Angeles, or 24 hours. 

$ TZ=America/Sao_Paulo seconds_in_day 2016-02-19 
2016-02-19 had 86400 secs in America/Sao_Paulo, or 24 hours. 
$ TZ=America/Sao_Paulo seconds_in_day 2016-02-20 
2016-02-20 had 90000 secs in America/Sao_Paulo, or 25 hours. 
$ TZ=America/Sao_Paulo seconds_in_day 2016-02-21 
2016-02-21 had 86400 secs in America/Sao_Paulo, or 24 hours. 

$ TZ=America/Sao_Paulo seconds_in_day 2016-10-15 
2016-10-15 had 86400 secs in America/Sao_Paulo, or 24 hours. 
$ TZ=America/Sao_Paulo seconds_in_day 2016-10-16 
2016-10-16 had 82800 secs in America/Sao_Paulo, or 23 hours. 
$ TZ=America/Sao_Paulo seconds_in_day 2016-10-17 
2016-10-17 had 86400 secs in America/Sao_Paulo, or 24 hours. 

$ TZ=Australia/Lord_Howe seconds_in_day 2016-04-02 
2016-04-02 had 86400 secs in Australia/Lord_Howe, or 24 hours. 
$ TZ=Australia/Lord_Howe seconds_in_day 2016-04-03 
2016-04-03 had 88200 secs in Australia/Lord_Howe, or 24.5 hours. 
$ TZ=Australia/Lord_Howe seconds_in_day 2016-04-04 
2016-04-04 had 86400 secs in Australia/Lord_Howe, or 24 hours. 

$ TZ=Australia/Lord_Howe seconds_in_day 2016-10-01 
2016-10-01 had 86400 secs in Australia/Lord_Howe, or 24 hours. 
$ TZ=Australia/Lord_Howe seconds_in_day 2016-10-02 
2016-10-02 had 84600 secs in Australia/Lord_Howe, or 23.5 hours. 
$ TZ=Australia/Lord_Howe seconds_in_day 2016-10-03 
2016-10-03 had 86400 secs in Australia/Lord_Howe, or 24 hours. 
+0

作品像一個魅力,謝謝! –

0

10月30日是最後夏天的時候這裏的變化在英國。我可以拿到25小時,以這種方式那天起殼:

t1=$(TZ='Europe/London' date --date='20161030' +%s) 
t2=$(TZ='Europe/London' date --date='20161031' +%s) 
echo $((($t2 - $t1)/3600)) 

我不能完全確定,這將在每一個bash shell中工作,並且可能需要調整一點點。