Dates 20 years in the future considered invalid - laravel

Laravel validator doesn't accept dates that are more than 20 years in the future:
Route::get('test', function() {
$input = ['date' => '2039-01-01'];
$rule = ['date' => 'date'];
$v = \Illuminate\Support\Facades\Validator::make($input, $rule);
return 'Fails: '.$v->fails();
});
The following example returns true, despite the fact that the date is correct. But when I change 2039 to 2037, it works. How can I do to make the validator always return false?

From Wikipedia on Unix time:
On systems where the representation of Unix time is as a signed 32-bit number, the representation will end after the completion of 2,147,483,647 (2^31 - 1) seconds from 00:00:00 on 1 January 1970, which will happen on 19 January, 2038 UTC, with the exact time depending on the unpredictable leap seconds. This is referred to as the "Year 2038 problem" where the 32-bit signed Unix time will overflow and will take the actual count to negative.
And from Laravel Validation docs:
date
The field under validation must be a valid date according to the strtotime PHP function.
This seems to depend on whether PHP is compiled to use 32-bit timestamps or 64-bit timestamps (see discussions here). If you have a 32-bit PHP, your only way forward would be to write your own validator, that doesn't depend on PHP's date parsing (or move over to a 64-bit PHP).

Related

How to convert a hex TimeDateStamp DWORD value into human readable format?

Can anyone explain how to convert a Hex TimeDateStamp DWORD value into human readable format?
I'm just curious as to how a value such as 0x62444DB4 is converted into
"Wednesday, 30 March 2022 10:31:48 PM"
I tried googling of course and could not find any explanation. But there are online converters available.
But I'm just interested in converting these values for myself.
Your value is a 32-bit Timestamp.
Your datetime value is a 32-bit Unix Timestamp: The number of seconds since 1/1/1970.
See https://unixtime.org/
In most programming languages you can work with the hexadecimal notation directly.
Implementation should not be done by one person alone, since a lot of engineering goes into it. Leap years, even leap seconds, timezones, daylight savings time, UTC... all these things need to be addressed when working with a timestamp.
I have added my rough calculation below as a demonstration. Definitely use an existing package or library to work with timestamps.
See the JavaScript code below for demonstration.
There I multiply your value by 1000 because JavaScript works in Milliseconds. But otherwise this applies the same to other systems.
let timestamp = 0x62444DB4;
let dateTime = new Date(timestamp * 1000);
console.log('Timestamp in seconds:', timestamp);
console.log('Human-Readable:', dateTime.toDateString() + ' ' + dateTime.toTimeString());
// Rough output, just for the time.
// Year month and day get really messy with timezones, leap years, etc.
let hours = Math.floor(timestamp/3600) % 24;
let minutes = Math.floor(timestamp/60) % 60;
let seconds = Math.floor(timestamp) % 60;
console.log('Using our own time calculation:', hours + ':' + minutes + ':' + seconds);

difference between Carbon::now()->format('Y-m-d') and Carbon::now(7)->format('Y-m-d')

i'm new in laravel
What is Difference between Carbon::now()->format('Y-m-d'); , Carbon::now(7)->format('Y-m-d'); And
Carbon::now()->subDay(7)->format('Y-m-d');
Thank You
as we can see, there is almost no difference between the three if we use the "dd" function, except of course on subDay which stands for "subtract day" (I think).
but if we remove the format function in all three and use the default format of the "now" function
We can see that
in the "now" function, carbon will return the current timestamps, this second, based on the timezone we set (in my case GMT + 7)
Because the parameter of the "now" function should be a string of timezone, so if we fill it with a number then carbon will return the default value, GMT -1.
As I explained above, Sunday will reduce the number of days the parameters entered, exactly at the current hour, minute, and second.
sorry for english, have a nice day

Why there is no inverse function for gmtime in libc?

In libc there are two functions to convert from system time to calendar time - gmtime and localtime, but only localtime has inverse function - mktime. Why there is no inverse function for gmtime, and if there shouldn't be any, why gmtime exists?
I've found this piece of code work satisfactorily:
namespace std {
time_t timegm(tm* _Tm)
{
auto t = mktime(_Tm);
return t + (mktime(localtime(&t)) - mktime(gmtime(&t)));
}
}
which satifies the test:
auto t1 = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
auto t2 = std::timegm(std::gmtime(&t1));
EXPECT_EQ(t1, t2);
To explain the existence of gmtime(), some context is required:
gmtime() will convert a timestamp representation (number of seconds since 1970-01-01 00:00:00) to broken-down time representation (aka, struct tm), assuming that the timestamp timezone is UTC:
The gmtime() function converts the calendar time timep to
broken-down time representation, expressed in Coordinated Universal
Time (UTC). It may return NULL when the year does not fit into an
integer. The return value points to a statically allocated struct
which might be overwritten by subsequent calls to any of the date
and time functions.
In the other hand, localtime() takes in consideration the [local] system timezone (including daylight saving):
The localtime() function converts the calendar time timep to
broken- down time representation, expressed relative to the user's
specified timezone. The function acts as if it called tzset(3) and
sets the external variables tzname with information about the
current timezone, timezone with the difference between Coordinated
Universal Time (UTC) and local standard time in seconds, and
daylight to a nonzero value if daylight savings time rules apply
during some part of the year.
Note that the number of seconds since 1970-01-01 00:00:00 differ from timezone to timezone (when it was 1970-01-01 00:00:00 in New York, it clearly wasn't in, for instance, Tokyo).
The mktime() converts a struct tm to a time_t value (number of seconds since 1970-01-01 00:00:00) based on the [local] system timezone, and should not be interpreted as the inverse of any particular function (such as localtime() or gmtime()), as the inverse term may be [wrongly] interpreted as a safe cross-system conversion:
The mktime() function converts a broken-down time structure,
expressed as local time, to calendar time representation. The
function ignores the values supplied by the caller in the tm_wday
and tm_yday fields. The value specified in the tm_isdst field informs
mktime() whether or not daylight saving time (DST) is in effect
for the time supplied in the tm structure: a positive value means DST
is in effect;
There is also a non-portable function (for GNU and BSD systems) called timegm(), which assumes a UTC timezone, such as gmtime() does.
References
Blockquoted text is retrieved from parts of release 3.74 of the Linux man-pages project.

What is the value of the ISO 8601 duration `P1M` (in seconds)?

Suppose I have an ISO 8601 duration, expressed as "P1M". Phrased colloquially, this means "one month." Is there a standard rule for converting this into a number of seconds, assuming the start date is not known?
For 30-day months, it might be 2,592,000.
For 31-day months, it might be 2,678,400.
In February, it might be 2,419,200 or it might be 2,505,600.
My gut says there's no way to resolve "one month" to an exact number of seconds without knowing context, and where those seconds are laid out on the calendar. But are there standard rules/conventions to calculate these durations in an abstract way?
From ISO 8601 documentation that I found (page 6 - http://xml.coverpages.org/ISO-FDIS-8601.pdf), it seems you are correct in that the number of seconds in a month cannot definitively be determined. However it does note that "In certain applications a month is regarded as a unit of time of 30 days", so depending on your application this may be a valid approach.
The distinction between "Calendar Time" (Years, Months, etc) and "Absolute Time" (Hours, Minutes, Seconds, etc) is sometimes an important one. As an example, some people might complain about having 13 mortgage payments some years if they paid every 30 days as opposed to every month.
You are right, an ISO 8601 duration is dependent of the context.
A duration is a period/an interval of time between two dates.
Example :
2020-01-01/2020-02-01 = P1M = P31D
2020-02-01/2020-03-01 = P1M = P29D
2019-02-01/2019-03-01 = P1M = P28D
If you want a fixed duration indepedent of the context, use the day notation P30D, P60D, P90D... instead.
The same applies for years :
2019-01-01/2020-01-01 = P1Y = P12M = P365D
2020-01-01/2021-01-01 = P1Y = P12M = P366D
If you can't have context information about a duration, for example P1M retrieved from database or given by user input, use by default today's context.
//What is a duration of one month in seconds ?
P1M = ? (no context)
//Use default context
Today = 2020-03-31
2020-03-31/P1M = 2020-03-31/2020-04-30
=> P1M = P30D
//A month contains 2 592 000 seconds

Are the Date, Time, and DateTime classes necessary?

What is the purpose of having Date and Time classes when there is a DateTime class that can handle both?
To summarize what the common ruby time classes are:
Time
This is the basic workhorse core ruby time class.
Has date and time attributes (year, month, day, hour, min, sec, subsec)
Based on floating-point second intervals from unix epoch (1970-01-01)
Can handle negative times before unix epoch
Can handle time arithmetic in units of seconds
Natively works in either UTC or "local" (system time zone)
There are really 3 kinds of Time object when it comes to dealing with time zones, let's look at a summer time to show DST:
utc = Time.utc(2012,6,1) # => 2012-12-21 00:00:00 UTC
utc.zone # => "UTC"
utc.dst? # => false
utc.utc? # => true
utc.utc_offset # => 0
local = Time.local(2012,6,1) # => 2012-06-01 00:00:00 -0700
local.zone # => "PDT"
local.dst? # => true
local.utc? # => false
local.utc_offset # => -25200
nonlocal = Time.new(2012,6,1,0,0,0, "-07:00") # => 2012-06-01 00:00:00 -0700
nonlocal.zone # => nil
nonlocal.dst? # => false
nonlocal.utc? # => false
nonlocal.utc_offset # => -25200
The last 2 look similar, but beware: you should not do arithmetic with a non-local Time. This is simply a time with a UTC offset and no zone, so it doesn't know the rules of DST. Adding time over the DST boundary will not change the offset and the resulting time-of-day will be wrong.
ActiveSupport::TimeWithZone
This one is worth mentioning here since it's what you use in Rails. Same as Time, plus:
Can handle any time zone
Respects DST
Can convert times between zones
I generally always reach for this when ActiveSupport is available as it takes care of all the time zone pitfalls.
Date
Has date attributes only (year, month, day)
Based on integer whole-day intervals from an arbitrary "day zero" (-4712-01-01)
Can handle date arithmetic in units of whole days
Can convert between dates in the ancient Julian calendar to modern Gregorian
Date is more useful than Time whenever you deal in whole days: no time zones to worry about! (I'm surprised this doesn't deal with the modern Persian calendar since it knows about the obsolete Julian calendar from centuries ago.)
DateTime
Has date and time attributes (year, month, day, hour, min, sec)
Based on fractions of whole-day intervals from an arbitrary "day zero" (-4712-01-01)
Can handle date arithmetic in units of whole days or fractions
Personally, I never have reason to use this: it's slow, it handles time without considering time zones, and it has an inconsistent interface. I find it leads to confusion whenever you assume you have a Time-like object, but it actually behaves like a Date instead:
Time.new(2012, 12, 31, 0, 0, 0) + 1 == Time.new(2012, 12, 31, 0, 0, 1)
DateTime.new(2012, 12, 31, 0, 0, 0) + 1 == DateTime.new(2013, 1, 1, 0, 0, 0)
Further, it has a meaningless "zone" attribute (note how non-local Time objects warn you that zone == nil), and you can't know anything else about it before turning it into a Time first:
dt = DateTime.new(2012,12,6, 1, 0, 0, "-07:00")
dt.zone # => "-07:00"
dt.utc? # => NoMethodError: undefined method `utc?'
dt.dst? # => NoMethodError: undefined method `dst?'
dt.utc_offset # => NoMethodError: undefined method `utc_offset'
Dealing with microseconds to check for rounding is also a little strange. You would think that because it doesn't have a usec attribute that it only deals in whole numbers, but you'd be wrong:
DateTime.now.usec # => NoMethodError: undefined method `usec'
DateTime.now.to_time.usec => 629399
In short, unless you're dealing with astronomical events in the ancient past and need to convert the Julian date (with time of day) to a modern calendar, please don't use DateTime. If anyone has an actual use case for this class, I'd love to read your comments.
I know there is an accepted answer but I have something to add. The Date class is a heavyweight, academic strength class. It can handle all sorts of RFC's, parse the strangest things and converts julian dates from thousand years ago to gregorian with the reform date of choice. The Time class is lightweight and it does not know of any of this stuff. It's cheaper and that shows up in a benchmark:
require 'benchmark'
require 'date'
Benchmark.bm(10) do |x|
x.report('date'){100000.times{Date.today} }
x.report('datetime'){100000.times{DateTime.now} }
x.report('time'){100000.times{Time.now} }
end
Result:
user system total real
date 1.250000 0.270000 1.520000 ( 1.799531)
datetime 6.660000 0.360000 7.020000 ( 7.690016)
time 0.140000 0.030000 0.170000 ( 0.200738)
(Ruby 1.9.2)
DateTime is a subclass of Date, so whatever you can do with Date can be done with DateTime. But as tadman and steenslag point out, DateTime is slower. See steenslag's answer for how much slower it is.
With respect to DateTime vs, Time, I found something here:
Time is a wrapper around Unix-Epoch.
Date (and DateTime) use rational and a "day zero" for storage. So Time is faster but the upper and lower bounds are tied to epoch time (which for 32bit epoch times is something around 1970-2040...while Date (and DateTime) have an almost infinite range but are terribly slow.
In short, DateTime is an all around superstar, and should be preferred in general, but if you want to optimize to the last bit, using Time can improve performance.
Another way of thinking of this is that Date and DateTime model time in terms of clocks and calendars, which is useful for describing times to users, and scheduling events. Having a Date without a time is nice for when you don't care about the time, and you don't want to think about time zones.
Time models time as a continuum, and is a wrapper around the Unix timestamp, which is just an integer. This is useful for all manner of internal applications where the computer doesn't care much whether a calendar boundary has been crossed, but just how many seconds (or milliseconds) have elapsed.
Yes. Date handles only the date for something, I.E., March 31, 1989. But it does not handle Time, for example, 12:30 PM.
DateTime, can handle both, March 31, 1989 12:30 PM EST.
Sometimes you don't need all parts of the DateTime. For example, you wanted to know when the use signed up for you website, Date would be useful here, because the time is eventually irrelevant.
In some cases you might want just the time. For example, if it's lunch time, you may want to tell the user your office is closed. At this point, the Data is irrelevant.
However, in most cases DateTime is used, because it can be used as either date, time, or both.

Resources