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;
}
Related
When I try to make a post request with React js to a make a reservation the time diminishes by two hours, while in the state it is exactly the time I wanted, meanwhile in the DB it is saved with two hours less. Example I try to save 11 o'clock instead saves 9 o'clock.
This is how format the date and time before passing it to the api call
const booking_date = new Date(year, month, day, hour, minute);
You can use a timestamp to get a more accurate consistent date
const booking_date = new Date(year, month, day, hour, minute).getTime();
Then if you need an actual date string you can convert it back to a date using new Date(). This is likely a timezone issue so a timestamp would mitigate that, along with giving you the extra bonus of being able to send less data in the api call.
Alternatively, if you NEED a string date you can use:
new Date().toUTCString()
which will convert the date to a UTC string that is consistent across the world (it will give you the same value no matter your location) since it uses the standardised UTC timezone.
See more here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date
You can use moment.js. If you have a date string then convert it using moment.js before sending the post request or if you do not have any date string, you just need to pick the current date and time means then you can use as like below with the desired format you need. I'd recommend to always use UTC internally, and convert to a timezone only when displaying the date to the user
import moment from "moment";
let date = moment().format('MM-DD-YYYY hh:mm:ss')} // It will return 06-16-2020 08:54:00
I am generating a file for export with the file name utcnow in the logic app expression which returns a value like this
utcNow()- "2020-06-01T15:41:15.5103915Z"
I want to convert it like "20200601154151" that means I need to remove some characters like" -","T" and millisecondsfollwed by Z,
I tried few combination of string format and I am not getting it right hoping you guys to help me.
Thanks,
There are many options for custom date formats. Here is a simple guide:
yyyy = Year (2020)
MM = Month (06)
dd = Day (01)
HH = Hour (15)
mm = Minute (41)
ss = Second (15)
Construct a format string (ex: yyyyMMddHHmmss) based on your requirements and pass it to formatDateTime:
formatDateTime(utcNow(), 'yyyyMMddHHmmss')
The resulting value will be '20200601154115'. There are many additional options at the link above.
Using angularjs, dynamodb as DB here.
I have a form where user saves some data. I save my "CreateOn" date in my dynamo db as:
DateTime.UtcNow.ToString("o");
//This saves date in DB as:2018-08-21T12:58:08.7823906Z
Storing like this because dynamo db requires dates (string) to stored in ISO8601 format if you want to use between operator to search for date range.
Now I have a search filters on my page which is basically an angular calendar. When the user selects the date in the calendar( start and end date) I want to get the data back based on the selected date. Here I am using moment to pass the calendar selected date to my api call as:
moment(createdOn).toISOString()
Eg: If they select the Today's date in the calendar I pass the selected date
(Tue Aug 21 2018 00:00:00 GMT-0400 (Eastern Daylight Time)) to the above function
The result of passing this date to moment(createdOn).toISOString() is
2018-08-21T04:00:00.000Z
The search condition at dynamo db is:
conditions.Add(new ScanCondition("CreatedOn", ScanOperator.Between, startDate, endDate ));
If the user selects from the calendar the start date as "08-20-2018" (2018-08-20T04:00:00.000Z) and the end date is "08-21-2018"(2018-08-21T04:00:00.000Z), the code all the data created b/w these 2 dates.
Now the issue is if they select same start and end date then the code does not returns any data, I believe because the start and end date is "2018-08-21T04:00:00.000Z" and the time part of this is all 0000 etc.
My question is how can I convert the date from my calendar ie my end date to correctly reflect the the end time which they select. I havent used ISO8601 format before so not sure how can I do so.
Thanks
You don't need moment for this. You can zero out the time using a Date in the following way.
const date = new Date('2018-08-21T12:58:08.7823906Z')
date.setUTCHours(0)
date.setUTCMinutes(0)
date.setUTCSeconds(0)
date.setUTCMilliseconds(0)
Then you can simply use toISOString() to format the date.
date.toISOString()
// returns '2018-08-21T00:00:00.000Z'
If you don't want to zero out the time, and instead want to set some specific time, you can use a similar approach, just substitute the 0 with whatever time you want.
Some other things to note: DynamoDB doesn't require any specific formatting for dates. DynamoDB simply does a string or number comparison depending on what the field is defined as. You could store your dates in DynamoDB as integers or another string format if you feel that would be easier to work with.
Also, I'm not sure how your table is setup but make sure that your "CreateOn" field is the Range key and that you are using Query, not Scan. Using the Scan operation doesn't scale well.
For example, using a date and time control, the user selects a date and time, such that the string representation is the following:
"6-25-2012 12:00:00 PM"
It so happens that this user is in the EST time zone. The string is passed to the server, which translates it into a .NET DateTime object, and then stores it in SQL Server in a datetime column.
When the date is returned later to the browser, it needs to be converted back into a date, however when the above string is fed into a date it is losing 4 hours of time. I believe this is because when not specifying a timezone while creating a JavaScript date, it defaults to local time, and since EST is -400 from GMT, it subtracts 4 hours from 12pm, even though that 12pm was meant to be specified as EST when the user selected it on a machine in the EST time zone.
Clearly something needs to be added to the original datetime string before its passed to the server to be persisted. What is the recommended way of doing this?
Don't rely on JavaScript's Date constructor to parse a string. The behavior and supported formats vary wildly per browser and locale. Here are just some of the default behaviors if you use the Date object directly.
If you must come from a string, try using a standardized format such as ISO8601. The date you gave in that format would be "2012-06-25T12:00:00". The easiest way to work with these in JavaScript is with moment.js.
Also, be careful about what you are actually meaning to represent. Right now, you are passing a local date/time, saving a local/date/time, and returning a local date/time. Along the way, the idea of what is "local" could change.
In many cases, the date/time is intended to represent an exact moment in time. To make that work, you need to convert from the local time entered to UTC on the client. Send UTC to your server, and store it. Later, retrieve UTC and send it back to your client, process it as UTC and convert back to local time. You can do all of this easily with moment.js:
// I'll assume these are the inputs you have. Adjust accordingly.
var dateString = "6-25-2012";
var timeString = "12:00:00 PM";
// Construct a moment in the default local time zone, using a specific format.
var m = moment(dateString + " " + timeString, "M-D-YYYY h:mm:ss A");
// Get the value in UTC as an ISO8601 formatted string
var utc = m.toISOString(); // output: "2012-06-25T19:00:00.000Z"
On the server in .Net:
var dt = DateTime.Parse("2012-06-25T19:00:00.000Z", // from the input variable
CultureInfo.InvariantCulture, // recommended for ISO
DateTimeStyles.RoundtripKind) // honor the Z for UTC kind
Store that in the database. Later retrieve it and send it back:
// when you pull it from your database, set it to UTC kind
var dt = DateTime.SpecifyKind((DateTime)reader["yourfield"], DateTimeKind.Utc);
// send it back in ISO format:
var s = dt.ToString("o"); // "o" is the ISO8601 "round-trip" pattern.
Pass it back to the javascript in moment.js:
// construct a moment:
var m = moment("2012-06-25T19:00:00.000Z"); // use the value from the server
// display it in this user's local time zone, in whatever format you want
var s = m.format("LLL"); // "June 25 2012 12:00 PM"
// or if you need a Date object
var dt = m.toDate();
See - that was easy, and you didn't need to get into anything fancy with time zones.
Here, I think this is what you are looking for:
How to ignore user's time zone and force Date() use specific time zone
It seems to me that you can do something like this:
var date = new Date("6-25-2012 12:00:00 PM");
var offset = date.getTimezoneOffset(); // returns offset from GMT in minutes
// to convert the minutes to milliseconds
offset *= 60000;
// the js primitive value is unix time in milliseconds so this retrieves the
// unix time in milliseconds and adds our offset.
// Now we can put this all back in a date object
date = new Date(date.valueOf() + offset);
// to get back your sting you can maybe now do something like this:
var dateString = date.toLocaleString().replace(/\//g,'-').replace(',','');
Blame the JSON.Stringfy()... and do:
x = (your_date);
x.setHours(x.getHours() - x.getTimezoneOffset() / 60);
I am using a filter before sending the date to the server:
vm.dateFormat = 'yyyy-MM-dd';
dateToSendToServer = $filter('date')(dateFromTheJavaScript, vm.dateFormat);
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.