I generate a date in MongoDB shell:
var d = new Date();
d
but the date result doesn't match the time in my location
However, the same code in javascript, the console.log(d) can output the correct time in my location
Why? How can I generate my local time in MongoDB?
This will give you the timezone (which you should store separately inside your application).
var myDate = new Date();
document.write(myDate.getTimezoneOffset());
MongoDB (including the console) will by default always generate and stores in UTC, however ISODates do support a timezone offset ( http://en.wikipedia.org/wiki/ISO_8601#Time_offsets_from_UTC ) however you would need to manage the creation of that offset from your application.
As #CRUSADER mentions it is normally better to store the users offset within the row or even not at all, particularly if your user could be accessing from many locations with many different timezones. In this case it might actually be better to modify the dates within your client JavaScript to take care of the difference in timezone from where they are currently accessing the page.
Related
I have an old app that let's users insert dates so everyone knows when they will be on vacation. Up until now, they had text field where they would enter text as they like ("1.1,5.1,21.1-25.1") or whatever they want as it is simple text field.
This kind of input excludes any chance of filtering or search.
I started playing with Yii not too long ago and this is first time i need to work with multiple dates and or date ranges.
What i need is advice on how to store those dates / date ranges into database? I know Yii has it's way to store single date (i have done it before), but i have no idea if it can work with date ranges and or multiple dates.
If any of you out there had similar problem i would apriciate your advice on how to store those dates and maybe extensions you used etc.
Of course i would like to make it user friendly with date pickers and search capabilities, but i'm taking it step by step. Once i have it stored correctly, searching and filtering wont be huge pain.
What i need is advice on how to store those dates / date ranges into database?
Well that depends on how do you want to use the date range. It depends on what is the criteria for searching. Because If you dont need to search the dates regularly then there may be some dirty ways to accomplish this task.
But if you need to search it frequently then you should make explicit columns for starting and end dates in the database table.By making explicit tables you can search in date ranges easily. for example you can run an sql query like
SELECT * FROM yourtable WHERE startDate<="some date" AND endDate>="some date"
NOTE:
You have to be careful about the format of date in your php code and format of date in database.
If you need to use date range just for calculation purposes then you can use simple php code to accomplish that.
$startDate = '2014-02-20';
$endDate = '2014-03-20';
$inputDate = '2014-02-28';
$start = strtotime($startDate);
$end = strtotime($endDate);
$input = strtotime($inputDate);
bool $isBetween=(($user >= $start) && ($user <= $end));
Yii way:
Actually there is not yii way to work with date range through one window. Actually each framework provide basic independent access to all attributes.That does not mean you cant change the behavior. Yes you can, but you need to code more. There are some extensions which you may find helpful in future
Adding a date range search for CGridView the easy way
How to filter CGridView with From Date and To Date datepicker
So I am trying to make a timesheeting app in meteor, creating projects and adding time entries. Why? it was all I could think of as a test app.
But, I'm more used to dealing with PHP, in PHP I would just store a date field with a time length. Right now, I'm wondering what's the best wat to deal with dates in Meteor.
Do… I do the same thing where I store a parsed string of the date, or is it a date time object? How would you deal with dates? (I'm only 3 hours into Meteor)
Meteor also includes the momentjs library which makes dealing with dates and times very easy. You get function to format and parse.
The best way to store your time is in a Date object. This is because in Mongo you will get the timestamp and its GMT deviation. Making the time TimeZone secure.
In order to manipulate and display times, use momentjs.
This community hackpad with recommended methods and packages for storing and using dates is pretty useful:
https://meteor.hackpad.com/Meteor-Cookbook-Using-Dates-and-Times-qSQCGFc06gH
The best way to represent dates on your collection documents is by directly using the Date object type. You can store Date objects directly into collection documents. If we are creating a document, we can generate a Date object as one of the properties supplied to the collection's insert() method.
I would suggest that you store the time in epoch. It will make it a lot easier to sort and search. Normally getTime() gets the time since the epoch in miliseconds but you can divide by 1000 to get the time in seconds.1
var d = new Date();
var seconds = d.getTime() / 1000;
To convert to the local date if you need it you can just
var d = new Date(0); // The 0 there is the key, which sets the date to the epoch
d.setUTCSeconds(seconds);
I'm using $where to query objects by month and date using code like the following to get UserInfo collections with a Birthdate of May 7:
db.UserInfo.find( function() {
var d = new Date(this.Birthdate);
return d.getDate() === 7 && d.getMonth() === 4;
});
This works perfectly locally, returning UserInfo objects with birthdates set to May 7th. However, this breaks remotely (Heroku+Mongolab) because I get back objects with Birthdate set to 1210222800000 for example, which is May 8th. Why is this happening and how can I get mongo to return the correct objects?
It looks like a time zone issue. I assume your dates are all supposed to be "midnight" on the day in question. This one is 8 hours off.
# TZ=UTC date -d #1210222800000
Tue Jun 8 08:00:00 UTC 40320
Since JSON doesn't really have a Date type, you have to be really clear where the conversion happens. Best practice is that it's the app's responsibility to always convert to UTC before sending to the database. (And to strip off the time if you're trying to just store a date. Otherwise your date comparisons will be wrong.)
It's also best practice to run your database servers and application servers in the UTC time zone. (The app should convert to local time if desired. Usually per-user since users are often in different time zones.)
I have a requirement to disregard records from the DB that are more than 10 minutes old. However, the DB server is present in a different time zone than the app server. I tried to leverage the time zone details from the timestamp column value but it seems that they do not store the time zone details in that column value (bad design?). However, i have found a way to get this information for the DB instance using a query:
select dbtimezone from dual.
However, most of the implementations in java support time zones via names and not offset information. I need to be able to translate this offset exactly to a timezone (EST etc) so that i may not miss any DST related time in my calculations. like so:
TimeZone dbZone = TimeZone.getTimeZone(10000); // offset is +10000
Calendar cal = Calendar.getInstance(dbZone);
cal.setTime(new Date());
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(dbZone);
Date parsedDate = df.parse(df.format(cal.getTime()));
The plan is to convert the present client/app time to the DB specific timezone time and perform the difference between the two.
This cannot be done in a query due to some restraints. Please do not ask me to write a query to get latest records etc. Must be done in Java.
Any tips?
I am guessing it might get you in the right direction. You can try the following so you know the offset from EST and can do the calculation accordingly:
SELECT TZ_OFFSET('US/Eastern') FROM DUAL;
So a return of -3:00 would mean it is PST time. Maybe you've already tried this?
One of our procedures lets users bulk-insert related records by picking a view and then hitting a ribbon button. The form is saved, a flag is set, and a plugin then does its job.
We are using a subgrid with a view selector to let users pick or create their own views on the fly. Once a view is selected, the number of results (provided is lte 5k) is shown.
When a plugin runs the very same fetchxml server side (Retrieve of userquery or savedquery, then Retrieve + FetchExpression), the results change. We get not only a different number of records but also some records are different.
We concluded that the issue has to do with timezones. Some filters included "on-or-after" operators along with date values.
Example:
<filter type="and">
<condition attribute="modifiedon" operator="on-or-after" value="2011-01-01" />
<condition attribute="modifiedon" operator="on-or-before" value="2011-12-31" />
</filter>
The plugin ran as admin. Changing the plugin user has no effect - as if the current user timezone is not considered when pulling out records from the CRM using a FetchExpression.
How can I ensure that a fetchxml expression returns the same results client-side and server-side?
Probably related: MSDN thread.
Thanks for your time.
Edit: following Daryl's suggestion, I ran a SQL trace. Results are puzzling. Dates are correctly offset for client-side queries (ran from CRM, i.e. Advanced Find) - this means the fetchxml is correctly translated using the user's timezone settings. This does not happen for the same query, server-side; the output SQL contains the date filters "as-is", with no timezone offset. I assumed the same translation happened no matter the origin of the query execution context.
Edit 2: A flag in an hidden region of code (my last debugging resort) was preventing the plugin from instantiating the service in the running user's context. Everything runs fine now. Thanks everyone for your time and your help, it's much appreciated.
When working with dates, always remember to convert to utc since that is how CRM stores them in the database.
The native CRM Advanced find is going to look at whatever the current user's time zone is, and convert that whatever time they enter into the advanced find to UTC before performing a SQL query. Your plugin control will need to do the same thing. These are the steps you'll need to perform before putting the criteria in the Fetch Xml / Linq Expression / Query Expression.
Get the user's UserSetting.TimeZoneCode via their SystemUserId.
Lookup the TimeZoneDefinition.StandardName for the TimeZoneCode from step 1
Call TimeZoneInfo.FindSystemTimeZoneById() passing in the Standard Name from step 2 (you can combine steps 1 and 2 into a single query, but I prefer to cache the results of step three using the input from step 1 for a slight performance improvement. ie. use a dictionary with the TimeZoneCode as the key and the TimeZoneInfo as the value)
Use this function to get the UTC value for the time that you're going to use in your plugin query:
public static DateTime ConvertTimeToUTC(DateTime time, TimeZoneInfo timeZone)
{
if (time.Kind != DateTimeKind.Unspecified)
{
// If the DateTime is created with a specific time zone(ie DateTime.Now), getting the offset will
// blow chow if it isn't the correct time zone:
// The UTC Offset of the local dateTime parameter does not match the offset argument.
//Parameter name: offset
// This quick check will recreate the serverLocal time as unspecified
time = new DateTime(
time.Year,
time.Month,
time.Day,
time.Hour,
time.Minute,
time.Second,
time.Millisecond);
}
var offest = new DateTimeOffset(time, timeZone.GetUtcOffset(time));
return offest.UtcDateTime;
}