Freemarker convert timestamp in milliseconds to date with time zone - freemarker

I am able to convert milliseconds to date using below format:
${createdTime?number_to_datetime?string("yyyy-MM-dd HH:mm:ss")}
Output is: 2021-07-22 11:02:38
Now I want to add a time zone Asia/Colombo to it, is there any way to add a time zone to freemarker number_to_datetime format?

As of 2.3.31, you can't directly pass a time zone to ?string. (You can to ?iso(timeZone), and its friends, but those output with ISO format only.)
But, you can change the time zone with <#setting time_zone='Asia/Colombo'>. After that, everything will be formatted in that time zone (during the same top-level template execution, I mean). That's probably unwanted though, and you want to change it back to whatever it was. In that case, the idea is this:
<#macro withTimeZone tz>
<#local lastTZ = .time_zone>
<#setting time_zone = tz>
<#nested>
<#setting time_zone = lastTZ>
</#macro>
So now you can do this:
<#withTimeZone "Asia/Colombo">${.now?string('yyyy-MM-dd HH:mm:ss')}</#>
Of course you could surround a bigger template section with this too.
Note that .time_zone was added in FreeMarker 2.3.31.

Related

How to convert Unix Time to (dd-MMM-yyyy) with FTL code

I am trying to convert a unix time to datetime depending on its locale given
Example I wanted to get locale Australia and convert UNIX time to date:
<#setting locale= getlocale>
<#assign unix = "1660545165"?number>
<#assign expiryDate = unix.getstarttime()?number?number_to_datetime?string["yyyy-mm-dd"]>
here is the time ${expiryDate}
I searched in google and suggested me to use getstarttime()?number?number_to_datetime?string["yyyy-mm-dd"]
However I am getting an error and currently stuck:
Expected a hash, but this has evaluated to a number
Lot of what's wrong I think is simply unnecessary there. Also based on the format you actually want a date, not a date-time. Here's a working example:
<#assign unixTime = 1660545165>
Here is the time: ${unixTime?number_to_date?string["yyyy-MM-dd"]}
Also usually you want to set the date_format setting to yyyy-MM-dd once (in the Java code, or with <#setting date_format = "yyyy-MM-dd"> near the top of the the template), and then just write ${unixTime?number_to_date} everywhere.

Ruby: How do I handle time zone offsets that include minutes

I have created an API endpoint that accepts a parameter called time_zone. I use this parameter to determine what time zone the requesting user is in. time_zone is a utc offset value that should be an integer. Example: MST has a UTC offset of -7.
This allows me to insert the passed in time_zone in the following line of code:
start_time = Time.now.in_time_zone(time_zone).beginning_of_day
The above works fine when the time_zone value is something simple like -7. However, if the time zone offset includes minutes, I run into trouble. Example: Venezuela is UTC-04:30. If I pass in '-430', I get ArgumentError: Invalid Timezone.
What value should I be passing into `Time.now.in_time_zone()' to get my example to work?
Thanks.
After much trial and error, I determined that I need to pass a decimal for time zone offsets that include minutes.
So, to address my previous example using Venezuela (UTC-04:30), I can simply pass in the value -4.5 and that works perfectly.
Similarly, for Nepal (UTC+05:45) I would pass in the value 5.75.

Get Windows Long Time Format

I'm trying to get the long time format in Windows (like "hh:mm:ss tt"). I can get the short time format like this:
GetLocaleInfoEx(NULL, LOCALE_STIMEFORMAT, format, 100);
I can't seem to find a constant for LOCALE_LTIMEFORMAT or anything like that. I can get the short time, short date and long date, but how can I query the current user's long time format?
As far as I can tell, windows defines the 'long' time format by LOCALE_STIMEFORMAT (set to something like "hh:mm:ss"), and the short time as LOCALE_SSHORTTIME (which, according to MSDN, is valid for Windows 7 and later).
Does that correspond to your findings, i.e. does it match the user preference in the Region and Language Control Panel item?
For the t specifier, if it is not included into the locale format, then either you are left with always using a custom format (like gbjbaanb said), or perhaps examining the format string for the presence of t or tt, and if absent adding it yourself (though, this might lead to odd results for cultures expecting the tt before the general time, for instance). This should not be necessary though, as the time format used by the locale is responsible for yielding time-strings that make sense (distinguishing between AM and PM, for instance).
What you are looking for is already included in LOCALE_STIMEFORMAT. Sample code:
wchar_t format[80]; // 80 is always enough
int ret = GetLocaleInfoEx(
LOCALE_NAME_USER_DEFAULT,
LOCALE_STIMEFORMAT,
format,
sizeof(format) / sizeof(*format));
if (ret == 0) die(GetLastError());
std::wcout << format << std::endl;
Output on my machine (I live in the USA):
h:mm:ss tt
The "tt" part will be absent for any culture or locale customization that does not display the AM/PM designator.
The LOCALE_STIMEFORMAT is the long time format. To get the short time format you can use LOCALE_SSHORTTIME starting with Windows 7 or cut off the seconds.
To confirm this simply change the long time format in your Control Panel / Region and Language settings.
Try using it with the LOCALE_S1159 and LOCALE_2359 constants which return the text for the AM/PM designators.
I think the issue is that time format is a time format, down to the second. You have to format it yourself if you want AM/PM just like you do with daylight savings time or timezone indicators.

Ruby Time doesn't keep offset when parsed

puts "date --- #{date}"
#date = Time.parse(date.to_s).iso8601 unless date.nil?
puts "#date -- #{#date}"
Outputs
Date --- 2012-08-12T12:15:17-07:00
#Date -- 2012-08-12T19:15:17+00:00
Anyone know why?
Additionally, this happens with strptime
Time.strptime("2012-08-12T12:05:08-07:00", "%Y-%m-%dT%H:%M:%S%:z")
=> 2012-08-12 19:05:08 +0000
It appears that your system is set to UTC. Time.parse() creates a new Time object, which uses the system timezone, and sets it to the time that is parsed. It doesn't change the timezone of the new Time to match the timezone of the parsed date. If you really want that behavior, you can use something like:
DateTime.parse(date.to_s).new_offset(date.iso8601[-6,6]).iso8601
Update: Regarding the strptime() part of the question that was just added, it's the exact same concept. A new Time is being created with the default timezone, with a time that matches the date that you're parsing.

Changing the timezone strings of date_lang.php

CodeIgniter stores timezones for its date class in
system/language/english/date_lang.php
I would like to change the strings in this file so that
$lang['UM12'] = '(UTC -12:00) Baker/Howland Island';
$lang['UM11'] = '(UTC -11:00) Samoa Time Zone, Niue';
would instead be
$lang['-12:00'] = '(UTC -12:00) Baker/Howland Island';
$lang['-11:00'] = '(UTC -11:00) Samoa Time Zone, Niue';
Is this possible at all?
Any change I make to the UM__ portion of one line makes it show as a blank on the dropdown. The remaining (unchanged) lines appear OK.
I have also tried to clone this file to application/language/english/ with similar bad results.
Any insights on this?
It looks like this would require hacks to the date_helper.php file which I am not willing to do.
Instead, the date class in CI has the timezones() function which allows you to convert from, for example, UM5 to -5. In that case one can wrap this function around the U__ value coming from the view/dropdown -- and then save it to DB as -5 or some other INT.
Since I want to show the user their selected timezone on that same dropdown, I am forced to have DB fields for the U__ and INT timezone formats. As far as I know, there is no CI function to convert from -5 to UM5.
So, for the user, I pull the U__ format into the view to autopopulate the dropdown.
For timezone conversions and such, I use the INT format.

Resources