Why Yii2 formatter asTime method return different time from asDateTime method?
Yii::$app->formatter->timeZone = 'Asia/Tehran';
date_default_timezone_set('Asia/Tehran');
var_dump(date_default_timezone_get()); //'Asia/Tehran'
var_dump(Yii::$app->timeZone); //'Asia/Tehran'
var_dump(Yii::$app->formatter->timeZone); //'Asia/Tehran'
var_dump(Yii::$app->formatter->asDatetime('now')); //'Aug 28, 2017, 3:22:25 PM'
var_dump(Yii::$app->formatter->asTime('now')); //'10:52:25 AM' Why it's different from the top
Since 2.0.12 Yii checks if value passed to asTime() contains information about time (hours, minutes, or seconds). If not (and now does not) it takes defaultTimeZone instead of timeZone (default is UTC).
If you want time in asDatetime() to be the same as asTime() you need to set Yii::$app->formatter->defaultTimeZone = 'Asia/Tehran'; but remember it might impact other code and database records saving.
Avoid time zone conversion for date-only asDate() and time-only asTime() values.
private function formatDateTimeValue($value, $format, $type)
Related
I have to write a query calculating the time difference in years between two dates. One of the dates is fetched from the database whereas the other is a LocalDate. Following is the code I have written:
Expression<String> year = new UnitExpression(null, String.class, "YEAR");
LocalDate date=LocalDate.of(2018, 04, 30);
Expression<Integer> timeDiff = builder.function(
"TIMESTAMPDIFF",
Integer.class,
year ,
propertyListRoot.get("rentStartDate"),
date);
where UnitExpression is a custom class extending BasicFunctionExpression . However, this gives a compile time error saying
Required type Expression<?> Provided LocalDate
I researched a bit and tried
criteriaBuilder.literal(date)
This resolves the compile time error but doesn't compute the right value. What can be a possible solution? What am I missing here?
The mistake I was making was not converting the arguments of the function to Timestamp. This works fine:
Expression<Integer> timeDiff = builder.function(
"TIMESTAMPDIFF",
Integer.class,
year,
propertyListRoot.<Timestamp>get("rentStartDate"),
builder.literal(Timestamp.valueOf(month))
);
Say we have a list of activities, for different clients, saved by date.
The date is saved in utc, and we know the client's timezone.
We want to know the amount of activies per day, in the client's timezone, while taking into account daylight saving times.
In mysql, we could use CONVERT_TZ(A.activity_date, 'UTC', S.timezone) As LocalDate and group by the the LocalDate.
In linq2db, we could get the offset of the timezone and add it to the utc date, however, that would not take into account DST.
Is there a method in linq2db that I have no yet found that could do this? If not, is there a way create a method that would map toCONVERT_TZ in linq2db?
A possible way to do this is to map the method CONVERT_TZ to a C# method as follows:
[Sql.Function("CONVERT_TZ", ServerSideOnly = true)]
public static DateTime? ConvertToTz(DateTime? i_Date, string i_TzFrom, string i_TzTo)
{
throw new InvalidOperationException();
}
ConvertToTz can then be called like any linq2db method, such as
...GroupBy(a => ConvertToTz(a.ActivityDate, "UTC", "America/Montreal"))
.Select(g => new {
Date = g.Key,
Count = g.Count()
})
I want to view time from db and then save it to another db.table in timestamp format, but I've get different time every time I convert it:
print_r($sub_datetime['datetime']);echo "<br>";
$temptime = Yii::$app->formatter->asTimestamp($sub_datetime['datetime']);
print_r($temptime);echo "<br> ";
$temptime2 = Yii::$app->formatter->asDatetime($temptime);
print_r($temptime2);echo "<br> ";
$temptime3 = Yii::$app->formatter->asTimestamp($temptime2);
print_r($temptime3);echo "<br> ";
Get:
10-5-2015 10:00
1431252000
10-5-2015 13:00
1431262800
The Issue
asTimestamp function assumes that the date you have specified is UTC by default and gives out the UTC time value.
asDatetime function however thinks otherwise and gets the system timezone, giving you back the date with the system timezone offset.
Solution
You have a few options, any one will work
Set the yii formatter timezone to utc Yii::$app->formatter->timeZone = 'UTC'; before calling asDatetime function (and set back to original if needed).
Before passing the timestamp to asTimestamp, offset it by your timezone to convert it to UTC.
After getting the result of asDatetime, offset it by timezone in order to convert it back to UTC
I have a column in mysql database named time_start which type is TIME.
I am trying to format the displayed time in my view from H:i:s to simple H:i, so instead of 20:00:00 i will get 20:00.
Firstly i thought i can use format() method, but it's supposed to be used with timestamps, so of course i get error Call to a member function format() on a non-object.
I'm sure it's a simple question, but i can't solve this.
-EDIT-
Forgt to mention. I am working with a many to many relationship and i'm calling my data like:
$schedule->time_start
Here i would like to show the time in H:i format, not H:i:s.
Have you tried an accessor method? I.e. in the Schedule model,
/**
* Return a truncated version of the timestamp.
* #param $value original value of attribute
* #return string truncated value
*/
public function getTimeStartAttribute($value)
{
// Input is HH:MM:SS
return substr($value, 0, 5);
// Output is HH:MM
}
Then $schedule->time_start ought to return the time in HH:MM format.
With a DateField component, the selectedDate.getHours returns as 24:00:00. I want it to return as 00:00:00.
Is there an easy way to do this?
Thanks!
UPDATE:
First, I set a variable in my Model that equals the selectedDate of a DateField component:
model.generalInfo.endDate = endDate_df.selectedDate;
Then I set another variable based on that value and I trace it out:
param.todate = df.format( model.generalInfo.endDate.toString() );
And this is where I see the time equal to 24:00:00
you could try something like
selectedDate.time = selectedDate.time - 24 * 60 * 60 * 60 * 1000
as a Date.time represents miliseconds since 1970 or whatever.. you substract 24 hours..
if it not works for you, you can create a new function or getter that converts it, or you can create a new mxml module, with DateField as superclass, and you can override the getHours method. tons of options to do this..
It looks like you are using the Flex DateFormatter to format the Date object. Have a look at the docs for this class, it has a formatString property that you can use to control how to output the date (or in this case the time).
If you give the DateFormatter a format string that contains "H" will output the hour in 24 hour format using the number range 1-24. If the format string contains "J" it will output the hour in 24 hour format using the range 0-23.
To get your desired output, use "JJ" in the format string, in addition to any other items. For example to output the hours, minutes, seconds:
var someDate:Date = new Date(2012, 11, 5);
var df:DateFormatter = new DateFormatter();
df.formatString = "JJ:NN:SS";
var formatted:String = df.format(someDate); // 00:00:00
Also, as #Flextras mentioned, there is Flash localization API you can use which has the added benefit of converting date/time strings to the values used by their locale. These are the DateTimeFormatter classes:
fl.globalization.DateTimeFormatter
spark.formatters.DateTimeFormatter (Flex 4)
These classes format dates into the user's locale (or one that you specifcy), and format Date objects the same way the DateFormatter does.