I'm using react widget date picker. (https://jquense.github.io/react-widgets/docs/#/datetime-picker?_k=c0gioy)
I'm passing date in this format : Sat Jul 15 2017 00:00:00 GMT+0530 (IST)
I'm using laravel in server side.
But date is saving one day less. It's saving as 2017-07-14 in database.
Can anyone please tell me the reason ?
Thank you.
In your config file, set an env variable called APP_TIMEZONE with whatever timezone you want it to use
if you are dealing with database timezone, add DB_TIMEZONE in .env file and set its value to the timezone you want
EDIT
the backup solution (if none was found), would be to create a custom function that calculates the offset between the client timezone and the server timezone. then use it to save the appropriate date to the database.
an example:
function date_default_timezone_offset_get()
{
$offset = timezone_offset_get(new \DateTimeZone(date_default_timezone_get()), new \DateTime());
return sprintf("%s%02d:%02d", ($offset >= 0) ? '+' : '-', abs($offset / 3600), abs($offset % 3600));
}
Related
So this is how my code looks like
cropref.child(mycrop.name).push({
cropname:mycrop.name,
croplocation:mycrop.location,
cropplantdate:mycrop.plantdate.toString(),
cropharvestdate:mycrop.harvestdate.toString(),
})
mycrop.harvestdate and mycrop.plantdate are both date inputs from my html
<input type="date" ng-model='mycrop.harvestdate'>
<input type="date" ng-model='mycrop.harvestdate'>
to be able to put the data on my Firebase database , I need to convert it first into string
cropplantdate:mycrop.plantdate.toString(),
but the data on my Firebase database includes time and timezone
sample data
Sat Dec 12 2020 00:00:00 GMT+0800 (Malay Peninsula Standard Time)
so once I call the data from my database, I can't filter it since it's not a date anymore but a string.
How do I solve this problem so that I can filter date (which is converted to string) stored inside my database
Two options
1) Store the date in a more generic, but human readable format, so right now would be Sunday November 27 at 09:13:38
20161127091338
2) Store the date as a unix timestamp (in milliseconds) using
(new Date).getTime() / 1000
There are a lot of variants to #2 so do some research to see which is best for your use case.
You can save either answer as a string but #1 would be more easily searchable since queries wouldn't require any kind of conversions - to see todays events
queryStartingAt("20161127") and queryEndingAt("20161127")
You need to convert the date first in your Format. You can use SimpleDateFormatFormat for that.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Now you can easily format your date to this format
String mynewdate = sdf.format(mycrop.plantdate.getTime());
The Output for today would be:
2016-11-27
Of course you can reverse that back to a Calendar. I do it this way:
public static Calendar fromStringtoCalendar(String datestring){
int year = Integer.valueOf(datestring.substring(0, 4));
int month = Integer.valueOf(datestring.substring(5, 7)) -1;
int day = Integer.valueOf(datestring.substring(8, 10));
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
return calendar;
}
I have 2016-10-21T13:47:02.922452 as ISO string from backend server.
My timezone is +0530 GMT i.e Offset is +530 (ahead of GMT).
When i use angular date expression like this
{{'2016-10-21T13:47:02.922452'| date:'medium':'+530'}}
I expected output to be = Oct 21, 2016 7:17:02 PM
but it prints
Oct 21, 2016 1:47:02 PM instead.
I am confused for what am i doing wrong here.
Do something like this
var d = new Date('2016-10-21T13:47:02.922452');
console.log(d)
Answering myself !
The easiest way that i figured out ! Make a custom filter
app.filter('IST', function($filter){
return function(val){
var date = new Date(val);
return $filter(date, 'medium');
}
})
Then use filter in expression like this -
{{'2016-10-21T13:47:02.922452'| IST}}
Custom filter will automatically convert ISO format string to Date object (browser timezone will automatically take care of timezone conversion.)
Date pipe transforms the date string you are passing ('2016-10-21T13:47:02.922452') to a Date object and then applies the time zone offset.
¿Whats the problem? When transforming '2016-10-21T13:47:02.922452' to a Date, it supposes that the date is in your local time, so the final calculation is wrong. For example, I am in +0200 so the transformation will be:
2016-10-21T13:47:02.922452 -> 2016-10-21T13:47:02.922452+0200 (Date object)
2016-10-21T13:47:02.922452+0200 -> 2016-10-21T18:17:02.922452+0530 (date changes with offset difference 0530-0200)
If your backend date is always in GMT timezone, just add Z to your date string: 2016-10-21T13:47:02.922452Z. This way, when creating the Date it will understand that the initial timezone is +0000
Solution:
{{'2016-10-21T13:47:02.922452Z' | date:'medium':'+0530'}}
We are using JavaMail API to send calendar entries. But the recipients of Outlook have time zone issues, as meetings show wrong timings. In general our approach is as follows:
First of all we have,
SimpleDateFormat iCalendarDateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss");
we then use iCalendarDateFormat.setTimeZone(TimeZone.getTimeZone(receiverTimeZone));
Finally, we use Calendar.getInstance() for start and end to manipulate Calendar fields,
and hence we have Date startDate = startTime.getTime();
Date endDate = endTime.getTime();
When we are about to send request as per icalendar specification we have ,
"DTSTAMP:" + iCalendarDateFormat.format(startDate) + "\n" +
"DTSTART:" + iCalendarDateFormat.format(startDate)+ "\n" "DTEND:" + iCalendarDateFormat.format(endDate)+ "\n"
Is this the correct approach?. Please comment.
Thanks
tl;dr
iCalendar format tracks the date-time separately from its intended time zone. You must juggle both parts appropriately.
Always use java.time classes. Never use legacy classes like Calendar & SimpleDateFormat.
Details
Caveat: I have not used iCalendar data before. So I may be incorrect in my understanding.
Looking at pages 31-33 of the RFC 5545 spec, it seems the authors of that spec assume you always want the date-time to be recorded separately from the time zone.
A moment, a point on the timeline, needs the context of a time zone or offset-from-UTC. For example, "noon on the 23rd of January next year, 2021" is not a moment. We do not know if you mean noon in Tokyo Japan, noon in Toulouse France, or noon in Toledo Ohio US — all very different moments, several hours apart.
To provide the context of an offset, a date and time must be accompanied by a number of hours-minutes-seconds such as 08:00. For an offset of zero hours-minutes-seconds, use +00:00.
2021-01-23T12:00:00+00:00
As an abbreviation of an offset of zero, +00:00, the letter Z can be used, pronounced “Zulu”. For example:
2021-01-23T12:00:00Z
But, strangely, the iCalendar spec wants to track the date and the time-of-day separate from the time zone. So this:
2021-01-23T12:00:00
…and a time zone field elsewhere:
America/New_York
And the iCalendar spec opts for the harder-to-read “basic” variation allowed by ISO 8601, which minimizes the use of delimiters. So this:
20210123T120000
For such a string, we must parse as a LocalDateTime. This class represents a date with a time-of-day but lacking any time zone or offset-from-UTC.
DateTimeFormatter f = dateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmss" ) ;
String input = "20210123T120000" ; // “Basic” variation of ISO 8601 format.
LocalDateTime ldt = LocalDateTime.parse( input , f ) ;
To determine a moment, we must apply a time zone. I assume iCalendar uses proper time zone names (Continent/Region format) and not the 2-4 letter pseudo-zones such as PST, CST, IST, and so on.
String zoneName = receiverTimeZone ; // Variable name taken from your code example, though you neglected to show its origins.
ZoneId z = ZoneId.of( zoneName ) ;
Apply the zone to get a ZonedDateTime, a moment, a point on the timeline.
ZonedDateTime zdt = ldt.atZone( z ) ;
Going the other direction, let's start with the current moment.
ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime now = ZonedDateTime.now( z ) ;
And generate string values for iCalendar.
DateTimeFormatter f = dateTimeFormatter.ofPattern( "uuuuMMdd'T'HHmmss" ) ;
String iCal_DateTime = now.format( f ) ;
String iCal_ZoneName = now.getZone().toString() ;
Never use the terrible legacy date-time classes bundled with the earliest versions of Java: Calendar, GregorianCalendar, java.util.Date, SimpleDateFormat, and so on. These were supplanted years ago by the modern java.time classes defined in JSR 310.
Hard to tell without seeing the actual content of your iCalendar file, along with the expected start and end datetime with timezone information but you seem to be generating the DTSTART in floating time (datetime with local time). Although your code sample seems to imply that you have access to the recipient's timezone (receiverTimezone), this is a very fragile approach.
Instead, you should use either the datetime with UTC time or the datetime with local time and timezone (where the timezone does not have to be the receiver timezone).
If the event is not recurring, the most simple approach is to use datetime with UTC time.
See https://www.rfc-editor.org/rfc/rfc5545#section-3.3.5 for the definition of each format.
I had same problem, for which I struggle lot. So below are my findings:
Outlook works smoothly with UTC Timezone. If we set date & time with UTC Timezone then outlook automatically converts this UTC Time into user corresponding Timezone. We will have to use 'Instant' object for DTSTART:, DTEND: and for DTSTAMP(Optional but recommended) also.
Quick Test just use "DTSTART:"+Instant.now() in ical String.
And in Java 8 for getting UTC Time java time API provides Instant.now() through which you can get your system time in UTC format. Java 8 also provides method like
a. Instant.ofEpochMilli() - This returns Instant which can directly use in ical Sting.
b. new Date().toInstant() Which returns UTC Instant object.
There are few scenarios where input date and time sources are different:
If you are fetching Date and Time from database then in this case database is not storing Timezone its only saving Date & Time. So first convert the Date & Time in that Timezone in which it was saved in database, in my case I was storing Date & Time after converting in 'EST' Timezone and Date value was of EST but time zone was not there in DB. So while fetching Date & Time value from DB I have appended Timezone in the Date value and then further converted to EPOC time using below method
public static long getEpocTimeWithTimezone(Date date) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DateTimeFormatter dateTimePattern = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(simpleDateFormat.format(date), dateTimePattern);
long epochInMilliSeconds = dateTime.atZone(ZoneId.of("America/New_York")).toEpochSecond() * 1000;
return epochInMilliSeconds;
}
Then Just Use as below code for ical String:
Instant startDt = Instant.ofEpochMilli(getEpocTimeWithTimezone(//pass your date here
)).truncatedTo(ChronoUnit.MINUTES);
Now set this Instant object(startDt) directly to "DTSTART:":
"DTSTART:"+startDt+"....then in same fashion "DTEND:" also.
In second scenario you have Date with Timezone (make sure after conversion you did not loses your actual Timezone, Like in 1st scenario after saving Date in DB we actually lost Timezone but it was showing Timezone IST that was dummy so be careful about this)
So in this case just assume myDateObject is Date object. So just get the Instant (which
will be in UTC) object from myDateObject by using toInstant() of Date class.
Instant startDt = myDateObject.toInstant().truncatedTo(ChronoUnit.MINUTES);
I am using .truncatedTo(ChronoUnit.MINUTES); because if we will not use this then
we might get some extra min or second in Meeting invite Time section.
So the final String for outlook mail should be some like:
.
.
.
"BEGIN:VEVENT\n"+
"DTSTART:"+startDt+"\n"+
"DTEND:"+endDt+"\n"+
.
.
.
VVI Note: Since Z is representation of UTC time zone, So just adding Z in the last of Time will not be UTC zoned Time, You will have to convert the Date & Time then only accurate time will come on Outlook. For verifying your Time is in UTC format or not just save the .ics attached file (which you got in Email) in local and check Date & Time are coming as DTSTART:2020-05-15T13:57:00Z or not If not then you are not converting the Date correctly in UTC.
I'm working on a project that was used only in one country but now is in using in several countries.
So I'm working in some DateTime issues, as you can image.
I'm using angular js for my frontend, python for my backend and Postgres as my database in this project.
To avoid any problem with DateTime and try to make more easy to work with the timezones I'm saving the DateTime in the database as UTC.
from DateTime import DateTime
# inside a class of my entity
self.start_date = datetime.utcnow()
This is working fine, the problem is when I try to convert the date back.
For example.
If my application is running in a country with GMT -1, when the user
asks to save the entity and it's 2016-07-13 15:00:00, in the database
(using the UTC now()) the DateTime will become 2016-07-13 16:00:00.
But when I try to get back the value I have two scenarios:
If I don't do anything, I'll receive the DateTime like it's on the database, "2016-07-13 14:00:00"
If I try to convert to the local timezone, I'm getting like 2016-07-13 17:00:00. The time was increased by 1 and not decrease was I expected.
I'm trying to use the momentjs library to work with dates, but nothing seems to work.
I'm wondering if what I supposed to do is get the GMT, like (-01:00) then do some math with the DateTime that comes from the database, like sub or sum the GMT hours difference.
Solution:
My solution for this was, store everything as UTC in my database.
Retrieve the datetime as UTC and covert to browsers timezone using momentjs library.
Doing like this.
moment.tz(moment.utc(datetime), moment.tz.guess());
I just learned that the JavaScript Date object apparently always stores the local time zone offset. When posting such a date to the server (using $http.post for example) the server gets the UTC date (local date minus time zone offset). That of course is right. In my case the server stores the date in a database.
When getting dates from the server (using $http.get for example) the server sends back the UTC date. If I directly bind these dates to a view the view displays the wrong date (the UTC date). To avoid that I found out that I must write a new Date instance to the model, passing the date I got from the server.
Problem is that this is a lot of work, especially if the server sends a model that actually should be directly bound to the view.
I am looking for a way to avoid having to create Date instances for each date property of models I got from the server in my controllers.
I have created this function that can be ran on the client, which adjusts the date by the current timezone offset. When the adjusted date is sent to the server, the DateTime object parsed from the post data will represent the same (local) date as seen on the client UI:
adjustDateByTimezoneOffset: function (date) {
// Javascript Date object stores the local timezone offset.
// On tranmission to the server the UTC date is sent. The server
// may not be timezone aware, and so this function facilitates
// adjusting to a date which can then be sent to a .NET web application and
// be recieved as a DateTime instance that equals the current (local) time on
// the client.
if (date && (date instanceof Date)) {
var timezoneOffsetMinutes = date.getTimezoneOffset();
var setMinutes = date.getMinutes() - timezoneOffsetMinutes;
date.setMinutes(setMinutes);
}
else {
throw "Input variable must be Date";
}
return date;
}