Related
I want to show an estimated delivery time in my shop.
If a customer orders before 4pm, he gets his order the next day.
But if the order is on a friday or on the weekend, he gets the order on the next monday.
That all works fine. But I need to add some holidays like christmas, new year and local holidays based on a state in my country.
I found a solution to identify the fixed and flexible (like easter) holidays in my state.
But I don't know how to work with them in the current function.
If an order is placed before one of these holidays I need to move the future date some days ahead.
Here's the current code (based on this code):
date_default_timezone_set( 'Europe/Berlin' );
$current_year = date('Y');
$next_year = date('Y', strtotime( $current_year." + 1 year" ));
// Holidays
$neujahr = date('d.m.Y',strtotime(date($next_year.'-01-01')));
$ostern = date('d.m.Y', easter_date($current_year));
$karfreitag = date( "l jS F", strtotime( $ostern." - 2 days" ) );
$ostermontag = date( "l jS F", strtotime( $ostern." + 1 days" ) );
$tagderarbeit = date('d.m.Y',strtotime(date('Y-05-01')));
$himmelfahrt = date( "l jS F", strtotime( $ostern." + 39 days" ) );
$pfingstmontag = date( "l jS F", strtotime( $ostern." + 50 days" ) );
$fronleichnam = date( "l jS F", strtotime( $ostern." + 60 days" ) );
$einheit = date('d.m.Y',strtotime(date('Y-10-03')));
$allerheiligen = date('d.m.Y',strtotime(date('Y-11-01')));
$weihnachten1 = date('d.m.Y',strtotime(date('Y-12-25')));
$weihnachten2 = date('d.m.Y',strtotime(date('Y-12-26')));
// if FRI/SAT/SUN delivery will be MON
if ( date( 'N' ) >= 5 ) {
$del_day = date( "l jS F", strtotime( "next monday" ) );
$order_by = "Monday";
}
// if MON/THU after 4PM delivery will be TOMORROW
elseif ( date( 'H' ) >= 16 ) {
$del_day = date( "l jS F", strtotime( "tomorrow" ) );
$order_by = "tomorrow";
}
// if MON/THU before 4PM delivery will be TODAY
else {
$del_day = date( "l jS F", strtotime( "today" ) );
$order_by = "today";
}
$html = "<br><div class='woocommerce-message' style='clear:both'>Order by 4PM {$order_by} for delivery on {$del_day}</div>";
echo $html;
The working method you are currently applying can work with multiple different if / else statements to check all conditions, so I prefer a different approach.
It goes as follows
As of today date 8 possible delivery dates are generated (expl: today = 14/07/2020,
possible dates are 14, 15, 16, 17, 18, 19, 20 & 21/07/2020
If today is already after 4 pm, the date of today expires (14/07/2020)
Less than 4 pm but a Friday, Saturday or Sunday, remove date
Then remove the (other) dates from the weekend: friday, saturday & sunday (17, 18, 19/07/2020)
Then all holidays (if any) are filtered out of the result
In the last step, the first value in the result is used and shown in the output message.
Note: It is easy to test by adjusting $today = date( 'd.m.Y' ); values to any date in the future, like $today = date( '25.12.2024' ); which would return
Delivery on Monday 30th December
25, 26 = holidays. 27, 28 & 29/12/2024 = friday, saturday & sunday
date_default_timezone_set( 'Europe/Berlin' );
// Today
$today = date( 'd.m.Y' );
// Possible delivery dates from today
for ( $i = 0; $i <= 7; $i++) {
$possible_delivery_dates[] = date( 'd.m.Y', strtotime( $today . '+' . $i . 'days' ) );
}
// Today ?
if ( date( 'H', strtotime( $today ) ) >= 16 ) {
// Today NOT possible
unset( $possible_delivery_dates[0] );
} elseif ( date( 'N', strtotime( $today ) ) >= 5 ) {
// Today (weekend) NOT possible
unset( $possible_delivery_dates[0] );
}
// Next Fri, Sat & Sun
$next_friday = date( 'd.m.Y', strtotime( $today . 'next friday' ) );
$next_saturday = date( 'd.m.Y', strtotime( $today . 'next saturday' ) );
$next_sunday = date( 'd.m.Y', strtotime( $today . 'next sunday' ) );
// Remove next fri, sat & sun
$possible_delivery_dates = array_diff( $possible_delivery_dates, [ $next_friday, $next_saturday, $next_sunday ] );
// Current & next year
$current_year = date( 'Y', strtotime( $today ) );
$next_year = date( 'Y', strtotime( $today . '+ 1 year' ));
// Holidays
$neujahr = date( 'd.m.Y', strtotime( date( $next_year . '-01-01' ) ) );
$ostern = date( 'd.m.Y', easter_date( $current_year ) );
$karfreitag = date( 'd.m.Y', strtotime( $ostern . '- 2 days' ) );
$ostermontag = date( 'd.m.Y', strtotime( $ostern . '+ 1 days' ) );
$tagderarbeit = date( 'd.m.Y', strtotime( date( $current_year . '-05-01') ) );
$himmelfahrt = date( 'd.m.Y', strtotime( $ostern . '+ 39 days' ) );
$pfingstmontag = date( 'd.m.Y', strtotime( $ostern . '+ 50 days' ) );
$fronleichnam = date( 'd.m.Y', strtotime( $ostern . '+ 60 days' ) );
$einheit = date( 'd.m.Y', strtotime( date( $current_year . '-10-03' ) ) );
$allerheiligen = date( 'd.m.Y', strtotime( date( $current_year . '-11-01' ) ) );
$weihnachten1 = date( 'd.m.Y', strtotime( date( $current_year . '-12-25' ) ) );
$weihnachten2 = date( 'd.m.Y', strtotime( date( $current_year . '-12-26' ) ) );
// Holidays (array)
$holidays = array( $neujahr, $ostern, $karfreitag, $ostermontag, $tagderarbeit, $himmelfahrt, $pfingstmontag, $fronleichnam, $einheit, $allerheiligen, $weihnachten1, $weihnachten2 );
// Remove holidays
$possible_delivery_dates = array_diff( $possible_delivery_dates, $holidays );
// First value
$first_val = reset( $possible_delivery_dates );
$html = 'Delivery on ' . date( 'l jS F', strtotime( $first_val ) );
echo $html;
I have php functions to get dates from this and next week. All is good except thursday - output from thursday is empty.
Here is my code:
$pondeli1 = date( 'd.m.Y', strtotime( 'monday this week' ) );
$utery1 = date( 'd.m.Y', strtotime( 'tuesday this week' ) );
$streda1 = date( 'd.m.Y', strtotime( 'wednesday this week' ) );
$ctrvtek1 = date( 'd.m.Y', strtotime( 'thursday this week' ) );
$patek1 = date( 'd.m.Y', strtotime( 'friday this week' ) );
$pondeli2 = date( 'd.m.Y', strtotime( 'monday next week' ) );
$utery2 = date( 'd.m.Y', strtotime( 'tuesday next week' ) );
$streda2 = date( 'd.m.Y', strtotime( 'wednesday next week' ) );
$ctrvtek2 = date( 'd.m.Y', strtotime( 'thursday next week' ) );
$patek2 = date( 'd.m.Y', strtotime( 'friday next week' ) );
And lines with "thursday next week" are not returning anything...
Where is problem please?
Try to use
$ctrvtek2 =strtotime("next Thursday",$ctrvtek1);
Getting the followoing error:
Warning: date() expects parameter 2 to be long, string given in
/home/users/2/catfood.jp-cybercat/web/academy/wp-includes/functions.php
on line 112
Which points to the line:
$datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
What changes are required to the above line to resolve this?
Here is the whole codes
function date_i18n( $dateformatstring, $unixtimestamp = false, $gmt = false ) {
global $wp_locale;
$i = $unixtimestamp;
if ( false === $i ) {
if ( ! $gmt )
$i = current_time( 'timestamp' );
else
$i = time();
// we should not let date() interfere with our
// specially computed timestamp
$gmt = true;
}
/*
* Store original value for language with untypical grammars.
* See https://core.trac.wordpress.org/ticket/9396
*/
$req_format = $dateformatstring;
$datefunc = $gmt? 'gmdate' : 'date';
if ( ( !empty( $wp_locale->month ) ) && ( !empty( $wp_locale->weekday ) ) ) {
$datemonth = $wp_locale->get_month( $datefunc( 'm', $i ) );
$datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
$dateweekday = $wp_locale->get_weekday( $datefunc( 'w', $i ) );
$dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
$datemeridiem = $wp_locale->get_meridiem( $datefunc( 'a', $i ) );
$datemeridiem_capital = $wp_locale->get_meridiem( $datefunc( 'A', $i ) );
$dateformatstring = ' '.$dateformatstring;
$dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
}
$timezone_formats = array( 'P', 'I', 'O', 'T', 'Z', 'e' );
$timezone_formats_re = implode( '|', $timezone_formats );
if ( preg_match( "/$timezone_formats_re/", $dateformatstring ) ) {
$timezone_string = get_option( 'timezone_string' );
if ( $timezone_string ) {
$timezone_object = timezone_open( $timezone_string );
$date_object = date_create( null, $timezone_object );
foreach( $timezone_formats as $timezone_format ) {
if ( false !== strpos( $dateformatstring, $timezone_format ) ) {
$formatted = date_format( $date_object, $timezone_format );
$dateformatstring = ' '.$dateformatstring;
$dateformatstring = preg_replace( "/([^\\\])$timezone_format/", "\\1" . backslashit( $formatted ), $dateformatstring );
$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
}
}
}
}
$j = #$datefunc( $dateformatstring, $i );
/**
* Filter the date formatted based on the locale.
*
* #since 2.8.0
*
* #param string $j Formatted date string.
* #param string $req_format Format to display the date.
* #param int $i Unix timestamp.
* #param bool $gmt Whether to convert to GMT for time. Default false.
*/
$j = apply_filters( 'date_i18n', $j, $req_format, $i, $gmt );
return $j;
}
$datefunc is an alias obviously to php's date method. If that's the case, you are trying to get the month from passing a single integer 1-12. When you can't do that, you need to pass a timestamp to PHP's date method then depending on the attributes you pass as options will return you the following data. Then you are passing it to wordpress locale get_month method that returns the name of the month. You need to refactor your code, so that $i isn't a for loop variable. If you are just trying to get Jan - Dec just do
$i = 1;
$monthArray = [];
do {
// Just push the months to an array and pass it to the view
array_push($monthArray, $wp_locale->get_month($i);
$i++;
} while($i < 13);
Then do what you need to with it. If you are getting a record back from the DB, you need to access the appropriate value in the returned model. Otherwise you're passing an array object. If you are accessing a model you should do)
// Access the property that you intended to retrieve the month on.
$datemonth = $wp_locale->get_month( $datefunc( 'm', $i['published_at'] ) );
I added a plugin called "paid membership pro" and this plugin was written in English and I translated into Japanese. There were lots of codes like this:
<?php printf(__('課金 #%s ( %s )', 'pmpro'), $pmpro_invoice->code, date_i18n(get_option('date_format'), $pmpro_invoice->timestamp));?>
I tried to change these codes as follows:
timestamp), $pmpro_invoice->code );?>
I guess that's why it caused the problem. What do you think?
Now I downloaded the plugin again and there is no problem.
Thank you for helping me.
I've been pulling my hair for hours for this. I'm trying to find all the positions of iframe The first occurrence is successful but not the second one.
Here's my code
$ofAllIFrames = qp( $this->content, 'iframe' );
$iframes = array();
$allIframes = array();
$startTag = 0;
foreach( $ofAllIFrames as $iframe) {
$startCurrentTag = strpos( $this->content, '<iframe>', $startTag );
$endCurrentTag = strpos( $this->content, '</iframe>', $startTag );
$iframes[] = array(
'start' => $startCurrentTag,
'end' => $endCurrentTag
);
$allIframes[] = $iframe;
$startTag = $endCurrentTag;
var_dump($startTag);
ob_flush();
}
return array(
'hasIFrame' => count( $allIframes ) > 0,
'elements' => $iframes
);
And this is my test case
public function test_if_content_has_multiple_iframes() {
$content = 'some content <iframe></iframe> <iframe id="1"></iframe> and another content';
$iframeChecker = new IFrame_Checker( $content );
$params = $iframeChecker->check();
$this->assertTrue( $params['hasIFrame'] );
$this->assertEquals( 13, $params['elements'][0]['start'] );
$this->assertEquals( 21, $params['elements'][0]['end'] );
$this->assertEquals( 31, $params['elements'][1]['start'] );
$this->assertEquals( 46, $params['elements'][1]['end'] );
}
And the test failed for the second iframe
1) Test_IFrame::test_if_content_has_multiple_iframes
Failed asserting that false matches expected 31.
$startCurrentTag = strpos( $this->content, '<iframe>', $startTag );
$endCurrentTag = strpos( $this->content, '</iframe>', $startCurrentTag );
Should work better.
Reason:
$startTag equals $endCurrentTag from the previous loop which refers to the offset at </iframe>.... So this is going to return the same position if you use $endCurrentTag = strpos( $this->content, '</iframe>', $startTag );
Last week a released a 2.0 beta version of my Events Manager plugin, which produces a list of events. Among the many bugs floating around, there is one I cannot fix. The bug seems to manifest itself only on a tester's server with PHP 4.4.8; works allright on PHP 5.
When I try to use the H:i php time format, I always get midnight (00:00).
The issue is with the wordpress function mysql2date. This function is a wrapper around the date function.
I isolated the problem and inserted this in the website template:
echo (mysql2date("H:i", "0000-00-00 13:24:00"));
The result was
00:00
At first I thought it was a wordpress bug, but then I rewrote my function to employ date() straightaway. The result was even stranger, instead of midnight I got 11:59.
Quite strangerly, both mysql2date and date seem to work allright on every other part of the plugin. Also, as I said, I cannot reproduce the bug on my server, only 2 users signalled it.
Since I was asked, here's the mysql2date code; it's part of Wordpress:
/**
* Converts MySQL DATETIME field to user specified date format.
*
* If $dateformatstring has 'G' value, then gmmktime() function will be used to
* make the time. If $dateformatstring is set to 'U', then mktime() function
* will be used to make the time.
*
* The $translate will only be used, if it is set to true and it is by default
* and if the $wp_locale object has the month and weekday set.
*
* #since 0.71
*
* #param string $dateformatstring Either 'G', 'U', or php date format.
* #param string $mysqlstring Time from mysql DATETIME field.
* #param bool $translate Optional. Default is true. Will switch format to locale.
* #return string Date formated by $dateformatstring or locale (if available).
*/
function mysql2date( $dateformatstring, $mysqlstring, $translate = true ) {
global $wp_locale;
$m = $mysqlstring;
if ( empty( $m ) )
return false;
if( 'G' == $dateformatstring ) {
return gmmktime(
(int) substr( $m, 11, 2 ), (int) substr( $m, 14, 2 ), (int) substr( $m, 17, 2 ),
(int) substr( $m, 5, 2 ), (int) substr( $m, 8, 2 ), (int) substr( $m, 0, 4 )
);
}
$i = mktime(
(int) substr( $m, 11, 2 ), (int) substr( $m, 14, 2 ), (int) substr( $m, 17, 2 ),
(int) substr( $m, 5, 2 ), (int) substr( $m, 8, 2 ), (int) substr( $m, 0, 4 )
);
if( 'U' == $dateformatstring )
return $i;
if ( -1 == $i || false == $i )
$i = 0;
if ( !empty( $wp_locale->month ) && !empty( $wp_locale->weekday ) && $translate ) {
$datemonth = $wp_locale->get_month( date( 'm', $i ) );
$datemonth_abbrev = $wp_locale->get_month_abbrev( $datemonth );
$dateweekday = $wp_locale->get_weekday( date( 'w', $i ) );
$dateweekday_abbrev = $wp_locale->get_weekday_abbrev( $dateweekday );
$datemeridiem = $wp_locale->get_meridiem( date( 'a', $i ) );
$datemeridiem_capital = $wp_locale->get_meridiem( date( 'A', $i ) );
$dateformatstring = ' ' . $dateformatstring;
$dateformatstring = preg_replace( "/([^\\\])D/", "\\1" . backslashit( $dateweekday_abbrev ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])F/", "\\1" . backslashit( $datemonth ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])l/", "\\1" . backslashit( $dateweekday ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])M/", "\\1" . backslashit( $datemonth_abbrev ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])a/", "\\1" . backslashit( $datemeridiem ), $dateformatstring );
$dateformatstring = preg_replace( "/([^\\\])A/", "\\1" . backslashit( $datemeridiem_capital ), $dateformatstring );
$dateformatstring = substr( $dateformatstring, 1, strlen( $dateformatstring ) -1 );
}
$j = #date( $dateformatstring, $i );
/*
if ( !$j ) // for debug purposes
echo $i." ".$mysqlstring;
*/
return $j;
}
If you're interested, you can download the code of my plugin here, the problem is on line 613 of events-manager.php.
Can this have something to do with PHP or apache settings?
Thanks in advance for any suggestion.
Davide
Not a fix, but an alternative - use UNIX_TIMESTAMP in your mysql statement instead of converting it afterwards.
SELECT UNIX_TIMESTAMP(date_created) AS date
I guess I have solved this issue. The problem was 0000-00-00, apparently not a valid time mysql2date value in some PHP/MySql combos (quite understandably, I am looking at you, month 00...) . I ended up using echo (mysql2date("H:i", "2000-10-10 13:24:00"));
Since I am just interested in the hours and minute a more casual date does the job. Problem solved.