Strange DateTime behaviour in date validation in php 5.4 - datetime

I wrote a simple piece of code to validate the format of a date.
The format of the date in my case is d/m/y
List of tests that I run successfully
10/12/2019 DATE OK
aa/12/2019 DATE KO
10-12-2019 DATE KO
But there is this case that surprises me:
32/12/2019 DATE OK
Why does this happen?
Do I need to add controls on the range of days and months?
$value = '32-12-2019';
$checkDate = \DateTime::createFromFormat('d/m/Y', $value);
if ($checkDate) {
print("DATE OK");
} else {
print("DATE KO");
}

I'm using
public static function validateDate($date, $format = 'Y-m-d')
{
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) === $date;
}
It validates correctness of date and required format

Related

Convert a string into date in AIX unix

I need to extract the date part from a file in unix and add +1 day to the date and rename the file with the new date in it.
for ex:
sample file name: sample_file_name_01_31_2022_14_01_45_loadid.csv
I tried to extract the timestamp using substr which gives 01_31_2022_14_01_45. Now, the new date should be 02_01_2022_14_01_45 and the new file name should be sample_file_name_02_01_2022_14_01_45_loadid.csv
Given the AIX operating environment, which doesn't have GNU date installed by default (for the handy date -d ... functionality), I'd approach this problem with a perl script. The script below uses fairly common modules that should be available on an AIX system.
The basic idea behind the script is to loop over every given argument (one or more filenames) and:
extract the date/time fields from the filename
convert those fields into seconds-since-the epoch
add one day's worth of seconds
convert that new timestamp into the desired string format
rename the file
I encountered a slight complication while adding error-checking: the timelocal() function will croak (exit the script) if any of the given date/time fields are out of range. Because I wanted to be able to loop over any remaining arguments, I had to wrap that call in a Try-Catch block.
#!/usr/bin/perl -w
use strict;
use POSIX qw(strftime);
use Time::Local qw(timelocal);
use Try::Tiny;
sub rename_a_file {
my $filename = shift;
# extract date from filename
my ($prefix, $month, $day, $year, $hour, $minute, $second, $suffix);
unless (
($prefix, $month, $day, $year, $hour, $minute, $second, $suffix) =
$filename =~ /^(.*)_(\d{2})_(\d{2})_(\d{4})_(\d{2})_(\d{2})_(\d{2})_(.*)$/
) {
warn "Could not determine a timestamp from ${filename}; skipping\n";
return undef;
}
# local time in seconds-since-the-epoch
my $t;
# timelocal will die if any inputs are out of range; catch it
my $flag = 0;
try {
$t = timelocal($second, $minute, $hour, $day, $month - 1, $year - 1900);
} catch {
warn "Unable to convert time specification: $_";
$flag = 1;
};
return undef if $flag;
# add one day's worth of seconds
$t += 24 * 60 * 60;
# new timestamp in string format
my $newdate;
unless ($newdate = strftime("%m_%d_%Y_%H_%M_%S", localtime $t)) {
warn "Unable to convert new date to a string format: $!";
return undef;
}
# rename file using new date
unless (rename $filename, "${prefix}_${newdate}_${suffix}") {
warn "Unable to rename $filename: $!";
return undef;
}
return 1;
}
my $errors = 0;
for (#ARGV) {
unless (rename_a_file($_)) {
warn "Unable to rename: $_\n";
++$errors;
}
}
$errors = 255 if $errors > 255;
exit $errors;

symfony 3.4 Doctrine COUNT

this code works well to count how many "2014-01-01 00:00:00" there is in my column "session" but I want the day to be anything not only 01.
class BooknowRepository extends \Doctrine\ORM\EntityRepository
{
public function findAllOrderedByNb() {
return $this->createQueryBuilder('a')
->select('COUNT(a)')
->where('a.session = :session')
->setParameter('session', '2014-01-01 00:00:00')
->getQuery()
->getSingleScalarResult();
}
}
class BooknowRepository extends \Doctrine\ORM\EntityRepository
{
public function findAllOrderedByNb() {
return $this->createQueryBuilder('a')
->select('COUNT(a)')
->where('a.session LIKE :session')
->setParameter('session', '%2014-01%')
->getQuery()
->getSingleScalarResult()
;
}
}
Several dates
but I want the day to be anything not only 01
If I have understood you correctly, your want find count of dates from array. In SQL this is implemented using WHERE IN syntax — in Doctrine you are greatly encouraged to use $qb->expr()->in() method.
$sessions = ['2014-01-01 00:00:00', '2014-01-03 00:00:00'];
...
$qb = $this->createQueryBuilder('a');
...
$qb->select('COUNT(a)')
->where($qb->expr()->in('a.session', ':sessions'))
->setParameter('sessions', sessions)
Dotrine doc: https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/query-builder.html#high-level-api-methods
Date range
If you want to get count of rows in month/year you need set a interval until the start of the next month
->andWhere('a.session >= :startSession')
->andWhere('a.session < :finishSession')
->setParameter('startSession', '2014-01-01 00:00:00')
->setParameter('finishSession', '2014-02-01 00:00:00')

shortcode to insert text depending on day of week

I would like to create a shortcode of [time] that would display 6:00-7:00AM everyday except for Saturday or Sunday, as those two days would display the time 8:00-9:00AM. How would I do this?
This is what I have come up with...
// [time]
function displaytime(){
if (date('l') == 'Saturday' || date('l') == 'Sunday')){
echo '8:00-9:00AM';
}else{ //it's a weekday
echo '6:00-7:00AM';
}
}
add_shortcode('time', 'displaytime');
// end display time
What it currently looks like... (next to Sat and Sun it should display 8:00-9;00AM)
I have 7 shortcodes to display the next 7 days of the week. So perhaps this is what is causing it to not work correctly?
// [tomorrow]
function displaydate_tomorrow(){
return date('D, M j.', strtotime('+1 day'));
}
add_shortcode('tomorrow', 'displaydate_tomorrow');
// end tomorrows date
// [tomorrow2]
function displaydate_tomorrow2(){
return date('D, M j.', strtotime('+2 day'));
}
add_shortcode('tomorrow2', 'displaydate_tomorrow2');
// end tomorrows date2
// [tomorrow3]
function displaydate_tomorrow3(){
return date('D, M j.', strtotime('+3 day'));
}
add_shortcode('tomorrow3', 'displaydate_tomorrow3');
// end tomorrows date3
// [tomorrow4]
function displaydate_tomorrow4(){
return date('D, M j.', strtotime('+4 day'));
}
add_shortcode('tomorrow4', 'displaydate_tomorrow4');
// end tomorrows date4
// [tomorrow5]
function displaydate_tomorrow5(){
return date('D, M j.', strtotime('+5 day'));
}
add_shortcode('tomorrow5', 'displaydate_tomorrow5');
// end tomorrows date5
// [tomorrow6]
function displaydate_tomorrow6(){
return date('D, M j.', strtotime('+6 day'));
}
add_shortcode('tomorrow6', 'displaydate_tomorrow6');
// end tomorrows date6
// [tomorrow7]
function displaydate_tomorrow7(){
return date('D, M j.', strtotime('+7 day'));
}
add_shortcode('tomorrow7', 'displaydate_tomorrow7');
// end tomorrows date7
// [time]
function displaytime(){
if (date('D') == 'Saturday' || date('D') == 'Sunday'){
return '8:00-9:00AM';
}else{ //it's a weekday
return '6:00-7:00AM';
}
}
add_shortcode('time', 'displaytime');
// end display time
It's stated in the docs:
Note that the function called by the shortcode should never produce output of any kind. Shortcode functions should return the text that is to be used to replace the shortcode.
try with this, and don't hesitate to comment if there is any issue:
// [time]
function displaytime(){
if (date('l') == 'Saturday' || date('l') == 'Sunday'){
return '8:00-9:00AM';
}else{ //it's a weekday
return '6:00-7:00AM';
}
}
add_shortcode('time', 'displaytime');
// end display time
EDIT after question update: The reason it displays the same time for all 7 places is because your initial code tests date('l') which only consider current day, so it will display '6:00-7:00AM' everywhere if current day is not Saturday or Sunday, or else '8:00-9:00AM' everywhere. In addition to this, you are creating 8 different shortcodes when only 1 should be enough for the 7 days, and the last for the time should be merged too, or else it has no way of knowing which day we consider.
EDIT 2: added code to set the wordpress timezone setting for the function, then restore to its original setting that was before the function.
updated code with a single shortcode for all (now you learn to add attributes to a shortcode!):
// use examples: [nextdaytime day="+1 day"] [nextdaytime day="+2 day"]
function displaynextdaytime($atts){
$originalZone = date_default_timezone_get(); //save timezone
date_default_timezone_set(get_option('timezone_string')); //set it to your admin value
$time = strtotime($atts['day']); //time for the date() function based on our 'day' attribute
if (date('l', $time) == 'Saturday' || date('l', $time) == 'Sunday'){
$timeStr = '8:00-9:00AM';
}else{ //it's a weekday
$timeStr = '6:00-7:00AM';
}
$returnVal = date('D, M j.', $time) . ' ' . $timeStr;
date_default_timezone_set($originalZone) //restore original zone
return $returnVal;
}
add_shortcode('nextdaytime', 'displaynextdaytime');
// end display next day and time

Difference between startDate and endDate-Symfony

Can someone assist me with this, I have a student table and I want to ensure that the user enters a date range from now to 3 months. I tried this but it didn't give me the results I wanted. Thinking about using datediff but not sure where I would put it. Is there another way like using a custom validation to validate the date.
* #Assert\Range
* (
* min= "today", max="+3 months"
* )
Error message:
This value should be a valid number.
#Assert\Callback(methods={"validatePayrollPeriod"})
public function validatePayrollPeriod(ExecutionContextInterface $context) {
$days = $this->startdate->diff($this->enddate)->days;
if ($days <= 7 || $days > 14) {
$context->buildViolation('Not a valid payroll period.')
->atPath('enddate')
->addViolation();
}
}
You could try to make a validation in your setter.
Something like
public function setEndDate($endDate)
{
if(your end date - your start date < 3){
$this->endDate= $endDate;
}else{
Throw whatever exepection you cant
}
return $this;
}

Moment JS - check if a date is today or in the future

I am trying to use momentjs to check if a given date is today or in the future.
This is what I have so far:
<script type="text/javascript" src="http://momentjs.com/downloads/moment.min.js"></script>
<script type="text/javascript">
var SpecialToDate = '31/01/2014'; // DD/MM/YYYY
var SpecialTo = moment(SpecialToDate, "DD/MM/YYYY");
if (moment().diff(SpecialTo) > 0) {
alert('date is today or in future');
} else {
alert('date is in the past');
}
</script>
The code is evaluating my date (31st of Jan 2014) as a date in past.
Any idea what I am doing wrong?
You can use the isSame function:
var iscurrentDate = startTime.isSame(new Date(), "day");
if(iscurrentDate) {
}
After reading the documentation: http://momentjs.com/docs/#/displaying/difference/, you have to consider the diff function like a minus operator.
// today < future (31/01/2014)
today.diff(future) // today - future < 0
future.diff(today) // future - today > 0
Therefore, you have to reverse your condition.
If you want to check that all is fine, you can add an extra parameter to the function:
moment().diff(SpecialTo, 'days') // -8 (days)
Since no one seems to have mentioned it yet, the simplest way to check if a Moment date object is in the past:
momentObj.isBefore()
Or in the future:
momentObj.isAfter()
Just leave the args blank -- that'll default to now.
There's also isSameOrAfter and isSameOrBefore.
N.B. this factors in time. If you only care about the day, see Dipendu's answer.
// Returns true if it is today or false if it's not
moment(SpecialToDate).isSame(moment(), 'day');
You can use the isAfter() query function of momentjs:
Check if a moment is after another moment.
moment('2010-10-20').isAfter('2010-10-19'); // true
If you want to limit the granularity to a unit other than milliseconds, pass the units as the second parameter.
moment('2010-10-20').isAfter('2010-01-01', 'year'); // false
moment('2010-10-20').isAfter('2009-12-31', 'year'); // true
http://momentjs.com/docs/#/query/is-after/
Update
moment().isSame('2010-02-01', 'day'); // Return true if we are the 2010-02-01
I have since found the isSame function, which in I believe is the correct function to use for figuring out if a date is today.
Original answer
Just in case someone else needs this, just do this:
const isToday = moment(0, "HH").diff(date, "days") == 0;
or if you want a function:
isToday = date => moment(0,"HH").diff(date, "days") == 0;
Where date is the date you want to check for.
Explanation
moment(0, "HH") returns today's day at midnight.
date1.diff(date2, "days") returns the number of days between the date1 and date2.
invert isBefore method of moment to check if a date is same as today or in future like this:
!moment(yourDate).isBefore(moment(), "day");
To check if it is today:
If we compare two dates which contain also the time information isSame will obviously fail. diff will fail in case that the two dates span over the new day:
var date1 = moment("01.01.2016 23:59:00", "DD.MM.YYYY HH.mm.ss");
var date2 = moment("02.01.2016 00:01:00", "DD.MM.YYYY HH.mm.ss");
var diff = date2.diff(date1); // 2seconds
I think the best way, even if it is not quick and short, is the following:
var isSame = date1.date() == date2.date() && date1.month() == date2.month() && date1.year() == date2.year()
To check if it is in the future:
As suggested also by other users, the diff method works.
var isFuture = now.diff(anotherDate) < 0
If you only need to know which one is bigger, you can also compare them directly:
var SpecialToDate = '31/01/2014'; // DD/MM/YYYY
var SpecialTo = moment(SpecialToDate, "DD/MM/YYYY");
if (moment() > SpecialTo) {
alert('date is today or in future');
} else {
alert('date is in the past');
}
Hope this helps!
Use the simplest one to check for future date
if(moment().diff(yourDate) >= 0)
alert ("Past or current date");
else
alert("It is a future date");
if firstDate is same or after(future) secondDate return true else return false. Toda is firstDate = new Date();
static isFirstDateSameOrAfterSecondDate(firstDate: Date, secondDate: Date): boolean {
var date1 = moment(firstDate);
var date2 = moment(secondDate);
if(date1 && date2){
return date1.isSameOrBefore(date2,'day');
}
return false;
}
There is isSame, isBefore and isAfter for day compare moment example;
static isFirstDateSameSecondDate(firstDate: Date, secondDate: Date): boolean {
var date1 = moment(firstDate);
var date2 = moment(secondDate);
if (date1 && date2) {
return date1.isSame(date2,'day');
}
return false;
}
static isFirstDateAfterSecondDate(firstDate: Date, secondDate: Date): boolean {
var date1 = moment(firstDate);
var date2 = moment(secondDate);
if(date1 && date2){
return date1.isAfter(date2,'day');
}
return false;
}
static isFirstDateBeforeSecondDate(firstDate: Date, secondDate: Date): boolean {
var date1 = moment(firstDate);
var date2 = moment(secondDate);
if(date1 && date2){
return date1.isBefore(date2,'day');
}
return false;
}
I wrote functions that check if a date of Moment type is a Day that Passed or not, as functional and self-descriptive functions.
Maybe it is could to help someone.
function isItBeforeToday(MomentDate: Moment) {
return MomentDate.diff(moment(0, 'HH')) < 0;
}
function isItAfterToday(MomentDate: Moment) {
return MomentDate.diff(moment(0, 'HH')) > 0;
}
Select yesterday to check past days or not with help of moment().subtract(1, "day");
Reference:- http://momentjs.com/docs/#/manipulating/subtract/
function myFunction() {
var yesterday = moment().subtract(1, "day").format("YYYY-MM-DD");
var SpecialToDate = document.getElementById("theDate").value;
if (moment(SpecialToDate, "YYYY-MM-DD", true).isAfter(yesterday)) {
alert("date is today or in future");
console.log("date is today or in future");
} else {
alert("date is in the past");
console.log("date is in the past");
}
}
<script src="http://momentjs.com/downloads/moment.js"></script>
<input type="date" id="theDate" onchange="myFunction()">
function isTodayOrFuture(date){
date = stripTime(date);
return date.diff(stripTime(moment.now())) >= 0;
}
function stripTime(date){
date = moment(date);
date.hours(0);
date.minutes(0);
date.seconds(0);
date.milliseconds(0);
return date;
}
And then just use it line this :
isTodayOrFuture(YOUR_TEST_DATE_HERE)
If we want difference without the time you can get the date different (only date without time) like below, using moment's format.
As, I was facing issue with the difference while doing ;
moment().diff([YOUR DATE])
So, came up with following;
const dateValidate = moment(moment().format('YYYY-MM-DD')).diff(moment([YOUR SELECTED DATE HERE]).format('YYYY-MM-DD'))
IF dateValidate > 0
//it's past day
else
//it's current or future
Please feel free to comment if there's anything to improve on.
Thanks,
i wanted it for something else but eventually found a trick which you can try
somedate.calendar(compareDate, { sameDay: '[Today]'})=='Today'
var d = moment();
var today = moment();
console.log("Usign today's date, is Date is Today? ",d.calendar(today, {
sameDay: '[Today]'})=='Today');
var someRondomDate = moment("2012/07/13","YYYY/MM/DD");
console.log("Usign Some Random Date, is Today ?",someRondomDate.calendar(today, {
sameDay: '[Today]'})=='Today');
var anotherRandomDate = moment("2012/07/13","YYYY/MM/DD");
console.log("Two Random Date are same date ? ",someRondomDate.calendar(anotherRandomDate, {
sameDay: '[Today]'})=='Today');
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
check with following:
let isContinue = moment().diff('2020-04-04T20:06:11+05:30')/1000
it is returning in seconds..
If will check as 2 mins condition then
if (isContinue < 120) {
..To check otp details or further logic
} else {
// otp is getting invalid
}
Simplest answer will be:
const firstDate = moment('2020/10/14'); // the date to be checked
const secondDate = moment('2020/10/15'); // the date to be checked
firstDate.startOf('day').diff(secondDate.startOf('day'), 'days'); // result = -1
secondDate.startOf('day').diff(firstDate.startOf('day'), 'days'); // result = 1
It will check with the midnight value and will return an accurate result. It will work also when time diff between two dates is less than 24 hours also.

Resources