On 2018-03-13 09:20 AM, Jared Chagnon wrote:
I setup a test script:


echo "`date`"
echo "`date +%z`"

currentdate=`date +%Y%m%d_%H%M%S`
echo "current date: $currentdate"

olddate=`date "+%Y%m%d_%H%M%S" --date='4 days ago'`
echo "old date 4 days ago: $olddate”

An unrelated suggestion:
There's no need to use backticks to execute date and return the value
and then echo it. Simply running 'date' will print the date to STDOUT.

  date +%z
  printf "current date: "
  date +%Y%m%d_%H%M%S

or even:

  date +"Current Date: %Y%m%d_%H%M%S"

————— Output —————

Tue Mar 13 09:08:34 EDT 2018
current date: 20180313_090834
old date 4 days ago: 20180309_080834

————— Notes ——————

My local time zone is America\New_York.  Please note the date modification is 
not using EDT and resulting in EST.

lets verify our baseline assumptions about New York time zones
are the same:

EST = Eastern Standard Time, used in autumn/winter = UTC-05:00.
EDT = Eastern Daylight Time, used in spring/summer = UTC-04:00.

In 2018, daylight saving time (DST) started on March 11th, 2:am.
"started" here means switching from EST to EDT.

That is:
  2018-03-09 is EST (still winter, DST not used).
  2018-03-13 is EDT (summer time, DST used).

This can be verified with:

  $ TZ="America/New_York" date +%F-%Z -d '2018-03-09'
  $ TZ="America/New_York" date +%F-%Z -d '2018-03-13'

in your example, the current date is 2018-03-13 (and implied: EDT),
and subtracting 4 days gives 2018-03-09.
Due to your time zone, 'date' knows that your timezone does use DST.
This date adjustment also crossed the DST change date (march 11th),
so date correctly adjusted the clock one hour backwards (from
09:08:34 to 08:08:34.

in newer version we've added a "--debug" option that helps
diagnosing such issues:

  $ TZ="America/New_York" \
     date --debug +%Y%m%d_%H%M%S_%Z --date="4 days ago"
  date: parsed relative part: -4 day(s)
  date: input timezone: TZ="America/New_York" environment value
  date: using current time as starting value: '21:13:23'
  date: using current date as starting value: '(Y-M-D) 2018-03-13'
  date: starting date/time: '(Y-M-D) 2018-03-13 21:13:23'
  date: warning: when adding relative days, it is recommended to \
            specify noon
  date: after date adjustment (+0 years, +0 months, -4 days),
  date:     new date/time = '(Y-M-D) 2018-03-09 20:13:23'
->date: warning: daylight saving time changed after date adjustment <-
  date: '(Y-M-D) 2018-03-09 20:13:23' = 1520644403 epoch-seconds
  date: timezone: TZ="America/New_York" environment value
  date: final: 1520644403.136862048 (epoch-seconds)
  date: final: (Y-M-D) 2018-03-10 01:13:23 (UTC)
  date: final: (Y-M-D) 2018-03-09 20:13:23 (UTC-05)

There is a subtle issue of how 'date' knows when to do DST adjustments
(and when not to).

When using 'date' without specifying the current date/time, it
gets the date,time and time zone from your operating system.

In your case it was "America/New_York". 'date' then checked the timezone
database and so it knows that NY does use daylight saving time,
and it knows that currently it is EDT, will subtract an hour when switching to EST.

When giving 'date' an explicit date without time zone, it doesn't
know if DST should be used or not - and assumes it should not be used.
Therefore it will not subtract an hour.

Observe the following:

  $ date +%F

  # Without timezone - hour stays the same:
  $ date -d '2018-03-13 09:00:00 4 days ago'
  Fri Mar  9 09:00:00 EST 2018

  # With timezone that indicates DST - hour is adjusted:
  $ date -d '2018-03-13 09:00:00 EDT 4 days ago'
  Fri Mar  9 08:00:00 EST 2018

These issues can be troubleshooted using the "--debug" option.

There is also one additional nuance:
If you don't specify the hour, 'date' assumes midnight.
If DST is active, it will subtract an hour resulting in 11pm
in the previous day:

  $ date -d '2018-03-13 4 days ago'
  Fri Mar  9 00:00:00 EST 2018

  $ date -d '2018-03-13 EDT 4 days ago'
  Thu Mar  8 23:00:00 EST 2018

This will be very confusing if one prints only the date, eg:

  $ date -d '2018-03-13 4 days ago' +%F

  $ date -d '2018-03-13 EDT 4 days ago' +%F

Therefore it is always recommended to use noon (12pm)
as explicit time when adjusting days (and when using --debug
there will be a warning to that effect).

If this explanation solves the issue - great.
If not, please provide further details and examples of the commands and
output you expect.

 - assaf

Reply via email to