• Chapter 11 Working with Dates and Times


    1.1 Formatting Dates for Display

    Use the date command with a strftime format specification.

    1. # Setting environment variables can be helpful in scripts:
    2. $ STRICT_ISO_8601='%Y-%m-%dT%H:%M:%S%z' # http://greenwichmeantime.com/info/iso.htm
    3. $ ISO_8601='%Y-%m-%d %H:%M:%S %Z' # Almost ISO-8601, but more human-readable
    4. $ ISO_8601_1='%Y-%m-%d %T %Z' # %T is the same as %H:%M:%S
    5. $ DATEFILE='%Y%m%d%H%M%S' # Suitable for use in a file name
    1. [maxwell@MaxwellDBA Day0801]$ STRICT_ISO_8601='%Y-%m-%dT%H:%M:%S%z'
    2. [maxwell@MaxwellDBA Day0801]$ ISO_8601='%Y-%m-%d %H:%M:%S %Z'
    3. [maxwell@MaxwellDBA Day0801]$ ISO_8601_01='%Y-%m-%d %T %Z'
    4. [maxwell@MaxwellDBA Day0801]$ DATEFILE='%Y%m%d%H%M%S'
    5. [maxwell@MaxwellDBA Day0801]$ date "+$IS0_8601"
    6. 2022-08-01 07:50:35 CST
    7. [maxwell@MaxwellDBA Day0801]$ gawk "BEGIN {print strftime(\"$ISO_8601\")}"
    8. 2022-08-01 07:50:49 CST
    9. [maxwell@MaxwellDBA Day0801]$ # Same as previous $ISO_8601
    10. [maxwell@MaxwellDBA Day0801]$ date '+%Y-%m-%d %H:%M:%S %Z'
    11. 2022-08-01 07:52:08 CST
    12. [maxwell@MaxwellDBA Day0801]$ date "+Program starting at: $ISO_8601"
    13. Program starting at: 2022-08-01 07:52:54 CST
    14. [maxwell@MaxwellDBA Day0801]$ printf "%b" "Program starting at: $(date '+$ISO_8601')\n"
    15. Program starting at: $ISO_8601
    16. [maxwell@MaxwellDBA Day0801]$ echo "I can rename a file like this: mv file.log file_$(date +$DATEFILE).log"
    17. I can rename a file like this: mv file.log file_20220801075507.log
    18. [maxwell@MaxwellDBA Day0801]$

    1.2 Supplying a Default Date

    Using the GNU date command,assign the most likely date to a variable, then allow the user to change it.

    1. [maxwell@MaxwellDBA Day0801]$ cat default_date.sh
    2. #!/usr/bin/env bash
    3. # cookbook filename: default_date.sh
    4. #Use Noon time to prevent a script running around midnight and a clock a few seconds off from causing off by one day errors.
    5. START_DATE=$(date -d 'last week Monday 12:00:00' '+%Y-%m-%d')
    6. while [ 1 ]; do
    7. printf "%b" "The starting date is $START_DATE,is that correct? (Y/new date) "
    8. read answer
    9. # Anything other than ENTER,"Y" or "y" is validated as a new date could use "[Yy]*" to allow the user to spell out "yes"...
    10. # validate the new date format as: CCYY-MM-DD
    11. case "$answer" in
    12. [Yy]) break
    13. ;;
    14. [0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9])
    15. printf "%b" "Overriding $START_DATE with $answer\n"
    16. START_DATE="$answer"
    17. ;;
    18. *) printf "%b" "Invalid date, please try again...\n"
    19. ;;
    20. esac
    21. done
    22. END_DATE=$(date -d "$DATE_DATE +7 days" '+%Y-%m-%d')
    23. echo "START_DATE: $START_DATE"
    24. echo "END_DATE: $END_DATE"
    25. [maxwell@MaxwellDBA Day0801]$

    1.3 Automating Date Ranges

    The -d option allow you to specify a specific date instead of using now,but not all date commands support it.

    1. [maxwell@MaxwellDBA Day0801]$ date '+%Y-%m-%d %H:%M:%S %Z'
    2. 2022-08-01 09:34:58 CST
    3. [maxwell@MaxwellDBA Day0801]$ date -d 'today' '+%Y-%m-%d %H:%M:%S %z'
    4. 2022-08-01 09:35:42 +0800
    5. [maxwell@MaxwellDBA Day0801]$ date -d 'yesterday' '+%Y-%m-%d %H:%M:%S %z'
    6. 2022-07-31 09:35:56 +0800
    7. [maxwell@MaxwellDBA Day0801]$ date -d 'tomorrow' '+%Y-%m-%d %H:%M:%S %z'
    8. 2022-08-02 09:36:08 +0800
    9. [maxwell@MaxwellDBA Day0801]$ date -d 'Monday' '+%Y-%m-%d %H:%M:%S %z'
    10. 2022-08-01 00:00:00 +0800
    11. [maxwell@MaxwellDBA Day0801]$ date -d 'this Monday' '+%Y-%m-%d %H:%M:%S %z'
    12. 2022-08-01 00:00:00 +0800
    13. [maxwell@MaxwellDBA Day0801]$ date -d 'last Monday' '+%Y-%m-%d %H:%M:%S %z'
    14. 2022-07-25 00:00:00 +0800
    15. [maxwell@MaxwellDBA Day0801]$ date -d 'next Monday' '+%Y-%m-%d %H:%M:%S %z'
    16. 2022-08-08 00:00:00 +0800
    17. [maxwell@MaxwellDBA Day0801]$ date -d 'last week' '+%Y-%m-%d %H:%M:%S %z'
    18. 2022-07-25 09:54:57 +0800
    19. [maxwell@MaxwellDBA Day0801]$ date -d 'next week' '+%Y-%m-%d %H:%M:%S %z'
    20. 2022-08-08 09:55:11 +0800
    21. [maxwell@MaxwellDBA Day0801]$ date -d '2 weeks' '+%Y-%m-%d %H:%M:%S %z'
    22. 2022-08-15 09:55:30 +0800
    23. [maxwell@MaxwellDBA Day0801]$ date -d '-2 weeks' '+%Y-%m-%d %H:%M:%S %z'
    24. 2022-07-18 09:55:39 +0800
    25. [maxwell@MaxwellDBA Day0801]$ date -d '2 weeks ago' '+%Y-%m-%d %H:%M:%S %z'
    26. 2022-07-18 09:55:54 +0800
    27. [maxwell@MaxwellDBA Day0801]$ date -d '+4 days' '+%Y-%m-%d %H:%M:%S %z'
    28. 2022-08-05 09:56:27 +0800
    29. [maxwell@MaxwellDBA Day0801]$ date -d '-6 days' '+%Y-%m-%d %H:%M:%S %z'
    30. 2022-07-26 09:56:40 +0800
    31. [maxwell@MaxwellDBA Day0801]$ date -d '2022-08-01 +12 days' '+%Y-%m-%d %H:%M:%S %z'
    32. 2022-08-13 00:00:00 +0800
    33. [maxwell@MaxwellDBA Day0801]$ date -d '3 months 1 day' '+%Y-%m-%d %H:%M:%S %z'
    34. 2022-11-02 09:57:59 +0800
    35. [maxwell@MaxwellDBA Day0801]$ date '+%a %Y-%m-%d'
    36. Mon 2022-08-01
    37. [maxwell@MaxwellDBA Day0801]$ date -d 'today''+%a %Y-%m-%d'
    38. date: invalid date ‘today+%a %Y-%m-%d’
    39. [maxwell@MaxwellDBA Day0801]$ date -d 'today' '+%a %Y-%m-%d'
    40. Mon 2022-08-01
    41. [maxwell@MaxwellDBA Day0801]$ date -d 'Saturday' '+%a %Y-%m-%d'
    42. Sat 2022-08-06
    43. [maxwell@MaxwellDBA Day0801]$ date -d 'last Saturday' '+%a %Y-%m-%d'
    44. Sat 2022-07-30
    45. [maxwell@MaxwellDBA Day0801]$ date -d 'this Saturday' '+%a %Y-%m-%d'
    46. Sat 2022-08-06
    47. [maxwell@MaxwellDBA Day0801]$ date -d 'next Saturday' '+%a %Y-%m-%d'
    48. Sat 2022-08-06
    49. [maxwell@MaxwellDBA Day0801]$ date -d 'this week Friday' '+%a %Y-%m-%d'
    50. Fri 2022-08-05
    51. [maxwell@MaxwellDBA Day0801]$

    The article presents five shell functions:

    1. pn_month
    2. Previous and next x months relative to the given month
    3. end_month
    4. End of month of the given month
    5. pn_day
    6. Previous and next x days of the given day
    7. cur_weekday
    8. Day of week for the given day
    9. pn_weekday
    10. Previous and next x day of weeks relative to the given day
    11. And these were added not long before this book went to press:
    12. pn_day_nr
    13. (Non-recursive) Previous and next x days of the given day
    14. days_between
    15. Number of days between two dates

    1.4 Converting Dates and Times to Epoch Seconds

    Use the GNU date command with the nonstandard -d option and a standard %s format:

    1. [maxwell@MaxwellDBA Day0801]$ # "Now" is easy
    2. [maxwell@MaxwellDBA Day0801]$ date '+%s'
    3. 1659319857
    4. [maxwell@MaxwellDBA Day0801]$ # Some other time needs the non-standard -d
    5. [maxwell@MaxwellDBA Day0801]$ date -d '2022-08-01 12:00:00 +0000' '+%s'
    6. 1659355200
    7. [maxwell@MaxwellDBA Day0801]$ perl -e 'print time, qq(\n);'
    8. 1659319953
    9. [maxwell@MaxwellDBA Day0801]$ # Same as above
    10. [maxwell@MaxwellDBA Day0801]$ perl -e 'use Time::Local; print timelocal(localtime()). qq(\n);'
    11. 1659320017
    12. [maxwell@MaxwellDBA Day0801]$ perl -e 'use POSIX qw(strftime); print strftime("%s",localtime()). qq(\n);'
    13. 1659320091
    14. [maxwell@MaxwellDBA Day0801]$ # The given time is in local time
    15. [maxwell@MaxwellDBA Day0801]$ perl -e 'use Time::Local; print timelocal("49","59","06","05","10","105") . qq(\n);'
    16. 1131145189
    17. [maxwell@MaxwellDBA Day0801]$ # The given time is in UTC time
    18. [maxwell@MaxwellDBA Day0801]$ perl -e 'use Time::Local; print timegm("49","59","06","05","10","105") . qq(\n);'
    19. 1131173989
    20. [maxwell@MaxwellDBA Day0801]$

    1.5 Converting Epoch Seconds to Dates and Times

    1. [maxwell@MaxwellDBA Day0801]$ EPOCH='1131173989'
    2. [maxwell@MaxwellDBA Day0801]$ date -d '2022-08-01 UTC $EPOCH seconds' '+%Y-%m-%d %T %z'
    3. date: invalid date ‘2022-08-01 UTC $EPOCH seconds’
    4. [maxwell@MaxwellDBA Day0801]$ date -d '2022-08-01 UTC $EPOCH seconds' +'%Y-%m-%d %T %z'
    5. date: invalid date ‘2022-08-01 UTC $EPOCH seconds’
    6. [maxwell@MaxwellDBA Day0801]$ date -d '2022-08-01 UTC $EPOCH seconds' + '%Y-%m-%d %T %z'
    7. date: extra operand ‘%Y-%m-%d %T %z’
    8. Try 'date --help' for more information.
    9. [maxwell@MaxwellDBA Day0801]$ date -d "1970-01-01 UTC $EPOCH seconds" +"%Y-%m-%d %T %z"
    10. 2005-11-05 14:59:49 +0800
    11. [maxwell@MaxwellDBA Day0801]$ date -d "2022-08-01 UTC $EPOCH seconds" +"%Y-%m-%d %T %z"
    12. 2058-06-05 14:59:49 +0800
    13. [maxwell@MaxwellDBA Day0801]$ date --utc --date "2022-08-01 $EPOCH seconds" +"%Y-%m-%d %T %z"
    14. 2058-06-05 06:59:49 +0000
    15. [maxwell@MaxwellDBA Day0801]$ perl -e "print scalar(gmtime($EPOCH)), qq(\n);" #UTC
    16. Sat Nov 5 06:59:49 2005
    17. [maxwell@MaxwellDBA Day0801]$ perl -e "print scalar(localtime($EPOCH)), qq(\n);" #Your local time
    18. Sat Nov 5 14:59:49 2005
    19. [maxwell@MaxwellDBA Day0801]$ perl -e "use POSIX qw(strftime); print strftime('%Y-%m-%d %H:%M:%S',
    20. > localtime($EPOCH)), qq(\n);"
    21. 2005-11-05 14:59:49
    22. [maxwell@MaxwellDBA Day0801]$

    1.6 Getting Yesterday or Tomorrow with Perl

    1. [maxwell@MaxwellDBA Day0801]$ # Yesterday at this same time (note subtraction)
    2. [maxwell@MaxwellDBA Day0801]$ perl -e "use POSIX qw(strftime); print strftime('%Y-%m-%d', localtime(time - 86400)), qq(\n);"
    3. 2022-07-31
    4. [maxwell@MaxwellDBA Day0801]$ # Tomorrow at this same time (note addition)
    5. [maxwell@MaxwellDBA Day0801]$ perl -e "use POSIX qw(strftime); print strftime('%Y-%m-%d', localtime(time + 86400)),qq(\n);"
    6. 2022-08-02
    7. [maxwell@MaxwellDBA Day0801]$

    1.7 Figuring Out Date and Time Arithmetic

    1. [maxwell@MaxwellDBA Day0801]$ CORRECTION='172800' # 2 days worth of seconds
    2. [maxwell@MaxwellDBA Day0801]$ # Code to extract the date portion from the data into $bad_date go here
    3. [maxwell@MaxwellDBA Day0801]$ # Suppose it's this:
    4. [maxwell@MaxwellDBA Day0801]$ bad_date='Jan 2 05:13:05' # syslog formated date
    5. [maxwell@MaxwellDBA Day0801]$ # Convert to Epoch using GNU date
    6. [maxwell@MaxwellDBA Day0801]$ bad_epoch=$(date -d "$bad_date" '+%s')
    7. [maxwell@MaxwellDBA Day0801]$ # Apply correction
    8. [maxwell@MaxwellDBA Day0801]$ good_epoch=$(( bad_epoch + $CORRECTION))
    9. [maxwell@MaxwellDBA Day0801]$ # Make corrected date human-readable
    10. [maxwell@MaxwellDBA Day0801]$ good_date=$(date -d "2022-08-01 UTC $good_epoch seconds") # GNU Date
    11. [maxwell@MaxwellDBA Day0801]$ good_date_iso=$(date -d "1970-01-01 UTC $good_epoch seconds" +'%Y-%m-%d %T') # GNU
    12. [maxwell@MaxwellDBA Day0801]$ echo "bad_date: $bad_date"
    13. bad_date: Jan 2 05:13:05
    14. [maxwell@MaxwellDBA Day0801]$ echo "bad_epoch: $bad_epoch"
    15. bad_epoch: 1641071585
    16. [maxwell@MaxwellDBA Day0801]$ echo "Correction: +$CORRECTION"
    17. Correction: +172800
    18. [maxwell@MaxwellDBA Day0801]$ echo "good_epoch: +$good_epoch"
    19. good_epoch: +1641244385
    20. [maxwell@MaxwellDBA Day0801]$ echo "good_date: +$good_date"
    21. good_date: +Sat Aug 4 05:13:05 CST 2074
    22. [maxwell@MaxwellDBA Day0801]$ echo "good_date_iso: $good_date_iso"
    23. good_date_iso: 2022-01-04 05:13:05
    24. [maxwell@MaxwellDBA Day0801]$
  • 相关阅读:
    13uec++多人游戏【创建和使用自定义组件】
    从图文展示到以云为核,第五代验证码独有的策略情报能力
    面对同样复杂的测试任务为什么大老很快能梳理解决方案,阿里十年测试工程师道出其中的技巧
    B站付费视频使up主掉粉过万
    【分布式】入门级NCCL多机并行实践 - 02
    pixel2的root过程
    比较含退格的字符串+每日温度
    powerbi从文本中提取想要的字段并分组
    cmake使用教程
    day34
  • 原文地址:https://blog.csdn.net/u011868279/article/details/126093432