Magento and BST Timezone issue - php

I running a Magento store in CentOS on top of a LEMP stack and I am trying to import orders from the website into our CRM using created_at date time of the order (so we can carry out delta updates).
The server's timezone is Europe/London and my php-fpm pool config (for my site) is said to be the same also:
php_admin_value[date.timezone] = Europe/London
I created an order and it correctly shows when the order was created at, for example:
However, if I looked at this order in the database, the created_at is set to one hour earlier (leads me to believe the BST timezone setting isn't in effect):
Does this mean Magento doesn't support BST? or is our magento setup incorrectly? or do I need a workaround (i.e. detect if daylight saving is on, then add/remove hour etc...)?
Update
This is how I have implemented give me all the orders since my last sync functionality, where $API_Data in the code below refers to last sync from server:
private function GetNewOrderIncrementIds($API_Data = '')
{
// Init
$now = new DateTime();
// Set Timezone to Europe/London (From Config)
$now->setTimezone(new DateTimeZone(Mage::getStoreConfig('mymodule_config/system_config/default_timezone')));
// Generate Date & Time
$fromDate = $API_Data;
$toDate = $now->format('Y-m-d H:i:s');
// Load Straight Order Sync Config
$sos_enabled = ((int)Mage::getStoreConfig('mymodule_config/order_sync/straight_order_sync_enabled'));
$sos_storeid = (int)Mage::getStoreConfig('mymodule_config/order_sync/straight_order_sync_storeid');
$sos_shipping = Mage::getStoreConfig('mymodule_config/order_sync/straight_order_sync_shippingmethod');
// Load Order Collection
$order_collection = Mage::getModel('sales/order')
->getCollection()
->addAttributeToFilter('created_at', array(
'from' => $fromDate,
'to' => $toDate
));
// Build Order Increment Id List
$new_orders = array();
foreach ($order_collection as $order)
{
// Check If This Order Is Straight Order Sync
$doSOS = ($sos_enabled &&
(int)$order->getStoreId() == $sos_storeid &&
$order->getShippingMethod() == $sos_shipping);
// Append Order
$new_orders[] = array(
'OrderNumber' => $order->getIncrementId(),
'DoSOS' => $doSOS
);
}
$order_collection = null;
// Finished
$this->API_Response(false, '', json_encode(array(
'LastSync' => $toDate,
'NewOrders' => $new_orders
)));
}

Magento sets script’s time relative to server time, converted to UTC. So each Magento store (database-wise) is synced to UTC. Read more # Guide through Magento’s timezones
To save created_at date use
Mage::getSingleton('core/date')->gmtDate()
To retrieve created_at store date use
Mage::helper('core')->formatDate($this->getCreatedAtStoreDate(), $format, true);
see /app/code/core/Mage/Core/Block/Abstract.php
To get order date
foreach ($order_collection as $order)
{
...
$created_at = Mage::helper('core')->formatDate($order->getCreatedAt(), 'medium', true);

Related

Return a function according to the date

I created a page (TheatrePage) in silverstripe that contains start date & finish date (and the Theatrepages is the children of TheatreHolder)
private static $db = [
'StartDate' => 'Date',
'FinishDate' => 'Date',
];
I need to loop through the first week & last week of these theatre in another page.
(e.g. a theatre StartDate=2018,11,01 & FinishDate=2019,03,15
if the today=2018,11,05{$Now} loop the in FirstWeekPage & if today{$Now}=2019,03,12 shown in LastWeekPage)
<?php
namespace Project;
use Page;
use PageController;
class FirstWeek extends Page {
private static $singular_name = 'FirstWeek';
private static $description = 'FirstWeek';
private static $table_name = 'FirstWeek';
}
class FirstWeekController extends PageController {
function InFirstWeek($limit = 99999)
{
if ("StartDate <= Now < StartDate + 7") {
return Theatre::get()->limit($limit)->sort('StartDate ASC');
}
}
}
Your Thatre class is like:
class Theatre extends Page
{
private static $db = [
'StartDate' => 'Date',
'FinishDate' => 'Date',
];
private static $default_sort = 'StartDate ASC';
}
If you want to get all Theatre Pages you have to run
Teatre::get();
This will return all Theatre pages, sorted by 'StartDate ASC', cause I defined that as default_sort in the class. Cleaner code is always good ;)
Now you want to get all Theatre pages, that start in this week. The SQL NOW() cannot be cached by MySQL, therefor we calculate it manually.
For calculating with dates we can use PHP's built in DateTime class:
$today = new DateTime('today');
// set time to midnight
$today = $today->setTime(0, 0);
MySQL format wants me to query in the format YYYY-MM-DD HH:MM:SS, so let's create the string:
$todayString = $today->format('Y-m-d H:i:s');
Now we can get all events that start today by filtering all events where StartDate is greater or equal today midnight:
$allTheatres = Theatre::get()->filter(['StartDate:GreaterThanOrEqual' => $todayString]);
Next we calculate the date string in a week. Therefor we add 7 days to today's DateTime object: add a DateInterval Object of one week:
$inAWeek = $today->add(DateInterval::createFromDateString('1 week');
But we want to include the whole day, so if it starts at 23:00hrs we still want it included, therefor let's set the time to one minute before midnight:
$inAWeek = $inAWeek->setTime(23,59);
and generate the string for the query:
$inAWeekString = $inAWeek->format('Y-m-d H:i:s');
Now get all Theatres that are in beween today AND in a week. From a database perspective we need all data sets, where start date is greater than today AND at the same time the start date is lesser than in a week. With SilverStripe's ORM we can filter like this, using search filter modifiers:
$allTheatresStartingThisWeek = Theatre::get()->filter([
'StartDate:GreaterThanOrEqual' => $todayString,
'StartDate:LessThanOrEqual' => $inAWeekString,
]);
The same works for the end date.
Now we want all Theatres that either start this week OR end this week. For OR filtering we need to use filterAny().
$allTheatresThisWeek = Theatre::get()->filterAny([
[
'StartDate:GreaterThanOrEqual' => $todayString,
'StartDate:LessThanOrEqual' => $inAWeekString,
],
[
'EndDate:GreaterThanOrEqual' => $todayString,
'EndDate:LessThanOrEqual' => $inAWeekString,
],
]);
Note: This returns a DataList, not the actual results, and you can refine it later in your template or another method.

avoid time/date overlapping in mysql (laravel)

I have an iOS app where users can reserve a car either daily or hourly and if a user reserves one car other user can't reserve it till the first reservation is over. I'm using Laravel as the API to save data to MySQL database.
The format of time and date are like this 27 Dec 2016 15:21. I'm saving the data
public function requested(Request $request)
{
$time = new Reservation();
$time->from_date = $request->from_date;
$time->to_date = $request->to_date;
$time->from_time = $request->from_time;
$time->to_time = $request->to_time;
}
but this won't prevent time overlapping for sure so I tried this
$carCount = Reservation::where(
function ($query) use ($startTime, $endTime) {
$query->where('from_time', '<', $endTime)
->where('to_time', '>', $startTime);
}
)->count();
if ($carCount > 0) {
return response()->json(['request' => 'no']); // this response just to check
} else {
$carRoom->save();
response()->json(['request' => 'yes']);
}
then I thought this isn't working because of date/time format. But I wanted to make sure what format I should convert the date in laravel?
this is my migration for Reservation:
$table->string('from_date')->nullable();
$table->string('to_date')->nullable();
$table->string('from_time')->nullable();
$table->string('to_time')->nullable();
I made the string because I wasn't sure if Time or anything is the right one
My main question is how can I avoid time and date overlapping in my app's database?
Store the dates in the database as timestamps
then your query should work as intended then convert the incoming dates:
27 Dec 2016 15:21
to timestamps using strtotime() or with datetime objects
both are part of PHP check the PHP documentation to see more information.

Laravel - Carbon ->addmonth() giving random dates?

We're having problems creating a webhook service for a payment using "Mollie".
Here's the webhook code
public function premiumPaymentCheck(Request $request)
{
$payment = Mollie::api()->payments()->get(Input::get('id'));
$metadata = $payment->metadata;
$user_id = $metadata->user_id;
if ($payment->isPaid()) {
$user = User::find($user_id);
$user->mollie_customerID = $metadata->customerId;
$user->premium = true;
$user->premium_type = "premium";
$user->subscribed = true;
$user->premium_expire_date = Carbon::now()->addMonth();
$user->save();
}
}
Everything works, except for the premium_expire_date. From what I understand, it should add 1 month from the payment time (the time the payment calls the webhook, so Carbon::now()), but the dates never match.It's always a random date that doesn't really make sense.
Some of the dates are correct, but most of them seem completely of. Any Idea what this might be?
There is no problem with carbon. Check your config/app.php file for timezone property.
'timezone' => env('APP_TIMEZONE', 'UTC'),
Timezone is currently:
'timezone' => 'UTC',
We are in Belgium/Brussels. So should it be:
'timezone' => env('Europe/Brussels', 'UTC')
Alternately it could be:
'timezone' => 'Europe/Brussels',
Thanks for the help!

How to set current date and time in table field using zend

I am having table called users with following fields ,
is_login(tinyint(1)) and last_login(datetime).
Below is the piece of code to update when user is online using Zend,
public function updateLastLoginDetails($id){
$currentDateTime = date('Y-m-d H:i:s');
$data = array('is_online' => 1,'last_login'=>$currentDateTime);
$this->_db->update( 'users', $data,'id = '.$id);
}
Here i am using $currentDateTime = date('Y-m-d H:i:s'); to store current data and time. But it seems not ok with time.
Kindly suggest me the best way to store current data and time using Zend .
Thanks in Advance,
Dinesh Kumar Manoharan
I'm not exactly sure what's causing your problem, but I find using NOW() to be easier. Also, you should ensure the variable $id gets quoted in the update's where condition.
public function updateLastLoginDetails($id){
$data = array('is_online' => 1, 'last_login' => new Zend_Db_Expr('NOW()'));
$this->_db->update('users', $data, array('id = ?' => $id));
}
It looks like you forgot to use $data anywhere in your code!
public function updateLastLoginDetails($id){
$currentDateTime = date('Y-m-d H:i:s');
$data = array('is_online' => 1, 'last_login'=>$currentDateTime);
$this->_db->update('users', $data, 'id = '. (int)$id);
}
You might want to consider using a TIMESTAMP field in place of a DATETIME for last_login and have MySQL update it automagically.
Hi am I understanding correctly that the year month and day are being inserted correctly but not the hour minutes and seconds? If that is the case can you please provide use with a describe of the users table. Just execute "DESCRIBE users" in phpMyAdmin.
If that is the case it could be that the field is of type DATE and not DATETIME.

How do I query in cakephp, if the date in the field 'created' of model 'listings' is more than 2 weeks ago?

I have a model 'listing' with a field 'created' which is in a datetime format.
I need to list in a view all listings that were created over 2 weeks ago.
An extra thing if possible is to somehow mark them as expired.
This is in cakePhp 1.27
Hi I think you can use a simple script to do that in cake.
function meScript(){
// first load your model if necessary
$listingModel = ClassRegistry::init('Listing');
// Then set your date margin to , two weeks back
$date_margin = date("Y-m-d H:i:s", strtotime('-2 week')) ;
// now retrieve all records that were created over 2 weeks ago
$listings = $listingModel ->find('all', array(
'conditions' => array('created <' => $date_margin),
)
);
}
That's pretty much it. Since the margin date is in "Y-m-d H:i:s" format, the " 'created <' => $date_margin" condition will retrieve all records that were created before that date.
As for the next step of marking them as expired:
Simply loop through the results and use their ids to set your 'expired' field (or whatever it is called in your database table) to 'true'.

Categories