Year 0 gets corrupted - datetime

$datetime = new DateTime('0000-00-00 00:00:00');
$date_string = $datetime->format('Y-m-d H:i:s');//-0001-11-30 00:00:00
date gets turned from 0000-00-00 00:00:00 to -0001-11-30 00:00:00
this is obviously wrong, why does this happen, how to fix it?
Should at least return false.
info:
PHP Version 5.2.13-0.dotdeb.1
Linux 2.6.26-2-openvz-amd64 #1 SMP Thu Nov 25 05:14:47 UTC 2010 x86_64

It's sort of correct by definition:
the zero-th day as opposed to the first yields a (hypothetical) minus one day
the zero-th month as opposed to the first yields a (hypothetical) minus one month
Take the (hypothetical) 1st of Jan in the year 0, subtract a month -> 1st of Dec in the year -1.
Subtract a day -> 30th of Nov in the year -1
Alternatively, they could have chosen to fix up the day first, then it'd go like:
1 Jan minus 1d -> 31st of Dec -0001, minus 1mo -> 30th of Nov -0001
The formatter obviously does the bound check to only produce valid dates. (For some definition of ``valid'')

Related

Representing an entire day or week or month as a number like timestamp

How can a day or week or month, essentially a range of time be represented by a single number?
The next interval would represent a number 1 more than the number for the previous interval, just how the next second is 1 more than the previous second, in timestamp representation.
Given a bunch of such numbers, the larger number simply means its representing a time interval afterwards in time, when compared to a number smaller than it.
Just realized if I stick to UTC and represent the day as YYYYMMDD, this becomes a number that I am looking for.
20180420 // 20 april 2018
20180421 // 21 april 2018
20180510 // 10 may 2018
20190101 // 1 jan 2019
This works for representing a day perfectly, I think.
For week, maybe do ceil() of days of current month divided by 7 for representing week as a number W and then using the format: YYYYMMW.
2018043 // 3rd week of april 2018
2018045 // 5th week of april 2018, though may not be the 5th week semantically but representation model works, greater than 4th week of april 2018 and smaller number than 1st week of may 2018
For month, simply YYYYMM works.
I feel so smart right now! 😄

What does the last number in UNIX timestamp mean?

I have a few UNIX timestamps that I've been converting back and forth, and I notice that the last number of the timestamp would change without causing any difference in the date.
For example, if you convert this number to normal date:
1452120848 > 6-1-16 17:54
But if you convert it back:
6-1-16 17:54 > 1452120840
As you can see the last number was changed to a zero. I tried some of the online converters and discovered that the last number could be any number and the date wouldn't change. What does it mean?
The unix time is the time in seconds since 1970.
You don't convert the seconds part of your date, thus it's 'lost' - your numbers may differ by up to 60.
The timestamp of 1452120848 is actually: Wed Jan 6 22:54:08 2016
So you're missing 8 seconds.
The UNIX timestamp gives you the seconds since 1st January 1970 00.00.00 UTC. Since this is seconds and you are just printing up to minutes, the difference is not shown.
However, they are not the same date:
$ date -d#1452120848
Wed Jan 6 23:54:08 CET 2016
$ date -d#1452120840
Wed Jan 6 23:54:00 CET 2016

gnu date - how come last month isn't?

I'm trying to use the date command to get the previous month. When I run it on the 31 of may, it returns may 1, I was expecting something in april. Is there better way to do this ?
> date --version
date (GNU sh-utils) 2.0
Written by David MacKenzie.
Copyright (C) 1999 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
> date
Fri May 31 13:29:08 EDT 2013
> date --date='last month'
Wed May 1 13:29:15 EDT 2013
per comment from #fvu I tried this :
> date --date='first day last month'
Thu May 2 14:00:43 EDT 2013
> date --date='first day next month'
Tue Jul 2 14:00:52 EDT 2013
which didn't quite work. this did though :
>date --date='last day last month'
Tue Apr 30 14:06:28 EDT 2013
guess I need the definition of month
"last month" is meant to be 30 days ago, not the previous month, I believe.
date --date="$(date +%Y-%m-15) -1 month"
is the info example given to detect the previous month because -1 month is the same as -30 days

understanding epoch time to calculate password ageing in unix

my_current_epoch=15684 equivalent time stamp is Thu, 01 Jan 1970 04:21:24
last_password_reset_epoch_time=15547 equivalent time stamp is Thu, 01 Jan 1970 04:19:07
I am not able to understand how difference of these two will give the days since last password reset.
As per my understanding epoch time is denoted in seconds that has elapsed since Jan 1,1970
Can someone please help me understanding this.
man 5 shadow on a Linux box says:
The date of the last password change is given as the number of days since Jan 1, 1970. The password may not
be changed again until the proper number of days have passed, and must be changed after the maximum number
of days. If the minimum number of days required is greater than the maximum number of day allowed, this
password may not be changed by the user.
So, you can find out to within 24 hours when a password was changed by multiplying the value from /etc/shadow by 86400 (the number of seconds in a day — but you didn't need me to tell you that, did you?).
For the values given (bc to the rescue):
15684*86400 = 1355097600
15547*86400 = 1343260800
And:
$ timestamp -u 1355097600 1343260800
1355097600 = Mon Dec 10 00:00:00 2012
1343260800 = Thu Jul 26 00:00:00 2012
$
Timestamp is my program; modern versions of date can handle this too. The -u means 'report in UTC (aka GMT)' rather than in my time zone.
"epoch" value in /etc/shadow = 15684
the seconds in 24 hours (because normally "epoch" value shows in seconds but for some reason (to make compact view, maybe) in /etc/shadow file "epoch" value displays in days, not in seconds) = 24 * 60 * 60 = 86400
And by multipliying these two numbers: 15684 (days) x 86400 (seconds per day); we will get the number 1355097600.
Afterwards, either using Epoch Converter by copy/paste the final result, you can get the date, or
just use date --date #$(( 15684 * 86400 )) command in cli

Excel 2007: Count backwards by month given a starting month

I am working in Excel 2007. My preference would be to do this without VBA. I am trying to count backwards a number of months starting from a given date. For example:
Start Date: July, 2010
Countdown: 12 months
Should result in:
Jun 2010
May 2010
Apr 2010
Mar 2010
Feb 2010
Jan 2010
Dec 2009
Nov 2009
Oct 2009
Sep 2009
Aug 2009
Jul 2009
So the seed month is month 0 and the countdown period can vary. I would like the month/year combination for display purposes but I also need the calculated value (ie, seed month is 0, next previous month is -1, etc) for calculations.
Any advice/help would be most appreciated!
It's relatively simple. For example, in cell A1, put "July 2010". In B1, put =DATE(YEAR(A1),MONTH(A1)-1,DAY(A1)) and in C1 put either =DATE(YEAR(A1),MONTH(A1)-2,DAY(A1)) or =DATE(YEAR(B1),MONTH(B1)-1,DAY(B1)) and so on.
If you're looking for a for/each type of statement with the number of months in the countdown, you'll need to go to VBA. Otherwise, you can prepopulate a range of cells with code like the above (You can start it with an if statement if the countdown cell has nothing, to display nothing).

Resources