This question already has answers here:
Using strtotime for dates before 1970
(7 answers)
Closed 7 years ago.
Hello guys is there a way to convert the date 0001-01-1 to a time format? I am trying to to use the php function strtotime("0001-01-01"), but it returns false.
My goal is to count the days from the date: 0001-01-01 to: 2011-01-01.
Use DateTime class. strtotime returns a timestamp which in your case will be out of int bounds.
As Ignacio Vazquez-Abrams has commented, dates before the adoption of the Gregorian calendar are going to be problematic:
The Gregorian calendar was adopted at different times in different countries (anywhere from 1582 to 1929). According to Wikipedia, a few locales still use the Julian calendar.
Days needed to be "removed" to switch to the Gregorian calendar, and the exact "missing" dates differ between countries (e.g. the missing days in September 1752). Some countries tried to do a gradual change (by removing February 29 for a few years); Sweden switched back to the Julian calendar to "avoid confusion", resulting in a year with February 30.
Years were not always counted from January 1 (which has left its legacy in things like the UK tax year).
Michael Portwood's post The Amazing Disappearing Days gives a reasonable summary.
In short, you have to know precisely what you mean by "1 Jan 1 AD" for your question to make any sense. Astronomers use the Julian Day Number (not entirely related to the Julian calendar) to avoid this problem.
EDIT: You even have to be careful when things claim to use the "proleptic Gregorian calendar". This is supposed to be the Gregorian calendar extended backwards, but on Symbian, years before 1600 observe the old leap year rule (i.e. Symbian's "year 1200" is not a leap year, where in the proleptic Gregorian calendar it is).
I am afraid it wont work since strtotime changes string to timestamp, which have lowest value of 0, and its at 1970-01-01.. cant go lower than that..
date('Y-m-d', 0);
You cannot do that this way. Here is one option how to do this.
$date1= "2011-01-01";
$date2 = "2011-10-03";
//calculate days between dates
$time_difference = strtotime($date2) - strtotime($date1);
now you got time difference in seconds from wich you can get days, hours, minutes, seconds.
From the manual:
If the number of the year is specified in a two digit format, the values between 00-69 are mapped to 2000-2069 and 70-99 to 1970-1999. See the notes below for possible differences on 32bit systems (possible dates might end on 2038-01-19 03:14:07).
You may want to give 'DateTime::createFromFormat' a shot instead this.
Also note that you cannot go below 1901 on a 32-bit version of PHP.
You can't use the function strtotime because this function return a timestamp and the time stamp start from 1970 so i advise you to searsh for a different way
Related
I am working for this association in my school and I am migrating web applications since, as of today, they are still running in PHP 4.4... But, I would like to quickly implement some fixes before changing to a newer PHP version.
One of these changes is related to dates comparison. The problem is I don't have strtotime and stuff like that, they all came in PHP 5.x.
I have to check if a timestamp is in one of two time intervals. In concrete:
I have a timestamp for when a person adhered to the association, school year goes from September 1st of year N to July 31st of year N+1, and I must check if the timestamp (and also the current time) lies
Between September 1st of year N and January 31st of year N+1, or
Between January 1st of year N+1 and July 31st of year N+1
So the question is what is the best way to do this? I came up with a solution: create my own timestamps and then compare. To create a timestamp for year N, I multiply the number of years since epoch time (N - 1970) by the number of seconds in a year ( 365.25 * 24 * 60 * 60 ). Then to that timestamp I add the number of seconds to September 1st, to January 1st, and so on. Finally I compare the whole. Isn't there a better way?
You are able to use PHP's strtotime function in PHP 4.4:
http://php.net/manual/en/function.strtotime.php
strtotime
(PHP 4, PHP 5, PHP 7)
strtotime — Parse about any English textual datetime description into a Unix timestamp
Here is an online example where you can run strtotime in 4.4.9:
http://sandbox.onlinephpfunctions.com/code/38559a58820d08105f746691bf338c565c1ed4e0
This question already has answers here:
PHP DateTime::modify adding and subtracting months
(19 answers)
Closed 6 years ago.
This is the first time I've ever used the built-in DateTime class, but we have to do calculations based on months previous/forward and are getting some interesting results when inputting day numbers that exist in one month but not another, and I'm not sure if PHP is really doing it accurately! (BTW, I've only tested this on v5.2 legacy code which I have to work on for now)
So for instance, if I input today's date (2016-10-31), subtract 6 months (with ->modify('-6 months')), the date outputted (with ->format('Y-m-d')) is May 1st! (2016-05-01). This implies PHP is just moving up the chain to the days in the next month (so 29 for Feb in a non-leap year is Mar 1, 30 is Mar 2, 31 is Mar 3, etc).
Using this logic, I deduced May 31 minus 1 month would be May 1st, which it was when I tested it!
Is this an accurate way to add/subtract by month? I'm not sure yet if our departments calculate this way, but I'm curious if anyone else has run into this.
This is a bit broad but...
The problem with how you're thinking is that
2016-10-31 - 6 months = 2016-04-30
PHP is thinking as such
$date = new DateTime('2016-10-31');
$date->modify('-6 months'); // PHP subtracts 183 days in all the tests I ran
echo $date->format('Y-m-d'); // 2016-05-01
You're going to have to come up with your own methodology because modify is basically a guesstimate for things like months, which can be 28-31 days long. In other words, PHP does a lot of things that are "good enough" if you don't need high precision.
I wanna know how many days the calendar started started. So I do this:
$beginning = Carbon::create(0, 1, 1)->startOfDay(); // is: 0000-01-01 00:00:00
$date = Carbon::now()->->startOfDay(); // is: 2016-05-25
$beginning->diffInDays($date)); // return: 736473
That correct, right?
I wanna make it possible to do the same in reverse. What is the date when the day is 800000? Is there somethign already for this in Carbon what I overlooked?
0000-01-01 is not a real date: there was no year 0! The year before 1 AD was 1 BC.
Generally speaking, using a date before 1582 AD as an epoch (i.e, a starting reference point) is inadvisable. The Gregorian calendar was established in 1582 AD -- it can be extended backwards to form the proleptic Gregorian calendar, but some software may handle this inconsistently.
That all being said, you should be able to use the Carbon->addDays() method to do what you're trying to accomplish here:
$date = $beginning->addDays(800000);
This question already has an answer here:
date_create_from_format() returns wrong value. [duplicate]
(1 answer)
Closed 6 years ago.
I am trying to create data from format using Datetime Class as following
$date = DateTime::createFromFormat('m-Y', '02-2016');
echo $date->format('Y-m-d');
Out put 2016-03-01, i was expecting to get 2016-02-01
is it a bug? or i am understating this function in a wrong way?
If you provide month and year, then PHP will provide a default day, using the current day of the current month (ie 30) today
That gives an effective 2016-02-30, which isn't a valid date..... but PHP allows these types of values where days is higher/lower than days in month, months are higher/lower than months in the year, and just increments/decrements to a valid date..... in this case, 1 additional day after the last day in month 2 or 2016 (29th February 2016) to give 1st March 2016
EDIT
Reference for day/month overflow/underflow behaviour
Note:
It is possible to over- and underflow the dd and DD format. Day 0 means the last day of previous month, whereas overflows count into the next month. This makes "2008-08-00" equivalent to "2008-07-31" and "2008-06-31" equivalent to "2008-07-01" (June only has 30 days).
It is also possible to underflow the mm and MM formats with the value 0. A month value of 0 means December of the previous year. As example "2008-00-22" is equivalent to "2007-12-22".
If you combine the previous two facts and underflow both the day and the month, the following happens: "2008-00-00" first gets converted to "2007-12-00" which then gets converted to "2007-11-30". This also happens with the string "0000-00-00", which gets transformed into "-0001-11-30" (the year -1 in the ISO 8601 calendar, which is 2 BC in the proleptic Gregorian calendar).
It's an known bug... or a documented feature, depending on how you look at it. See Mark Baker's answer for more details.
Workaround :
To get the date you expect, just add 01 to your input as a value for the day of the month.
$input = '02-2016';
$date = DateTime::createFromFormat('d-m-Y', '01-' . $input);
echo $date->format('Y-m-d');
// OUTPUT : 2016-02-01
I saw in PHP's documentation that there are two ways to format the year value in 4 digits:
Y - A full numeric representation of a year, 4 digits
o - ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0)
I researched more what the ISO-8601 is and it seems to be more "useful" or even accurate(?) based on php's documentation. I think it's more useful because it prevents ambiguity (like when handling date values like 1981-04-05).
But does it really make a difference? Is there some sort of "best practice"? Is 'o' slower that's why people use Y instead when they're not really doing anything complicated with the dates?
What specific use-cases perhaps is this useful?
Thank you for your help.
EDIT:
Thank you Jason for an example! I guess why I brought this up as well is I'm wondering why not just use 'o' all the time? I'm thinking I should just use 'o' all the time for currently unknown future specification that will require me to do more complex date operations.
o would be used when trying to determine the year of the current week (i.e. calendar week).
Y would be used for output of the year for a specific date.
This is shown by the following code snippet:
date('Y v. o', strtotime('2012-12-31')); // output: 2012 v. 2013
Not saying it makes it best-practice, but Y is more commonly used to output year. As noted, o would be incorrect/confusing to output the year for such boundary dates.
ISO 8601 is a very useful standard for representing dates, but it has several components, not all of which are useful for many purposes. In particular, the "ISO week" and "ISO year" can be slightly confusing terms, and they're often not what you really want to use (and if you do want to use them, you probably already know that).
Wikipedia has a pretty good explanation. Basically, the ISO 8601 standard defines a separate calendar that, instead of breaking up into months and days of the month, breaks up into weeks and days of the week.
You might think this wouldn't make a difference for specifying the year, but there's a little wrinkle: which year do the weeks near the beginning and end of the calendar year fit into? As Wikipedia says, it's not quite intuitive: "The first week of a [ISO] year is the week that contains the first Thursday of the [calendar] year."
The practical upshot: If you're representing dates as conventional year-month-day values, you don't want to use the "ISO year" (o). You won't notice the difference for most of the year, but as you get to December and January, suddenly you'll (sometimes) end up with dates that are a year off. If you just test your system with current dates, you can easily miss this.
Instead, you probably just want to be using plain old Y-m-d. Even though the date() documentation doesn't specifically say it, that's a perfectly valid ISO 8601 standard date.
Really, you should only be using o if you're using the ISO "week date" calendar (meaning you're likely also using W for the week number and N for the day-of-week).