Is there a way to force Sequelize use UNIX Timestamp as default time format both for createdAt/updatedAt timestamps and for custom-defined Sequelize.DATE field types?
Thanks!
P.S. I'm using MySQL
At any given moment in time, there are two possible dates (depending on one's position relative to the international date line): that is, converting from a UNIX timestamp to a date requires one to consider the timezone.
For example, the UNIX timestamp 946684800 is 2000-01-01 00:00:00Z. Whilst this represents the first day of the new millenium pretty much everywhere east of the Atlantic, it's still millenium eve everywhere to the west of that ocean. So which date does it represent?
Whilst it's possible to convert from a date to a timestamp, one must define one's own convention for so doing (e.g. represent a given date as midnight in UTC) or else the same date may be represented differently upon each encoding. Generally speaking, this is a bad idea which may have all sorts of unintended consequences.
There is a reason that the DATE data type exists: it is the correct way to store a date. Use it.
While eggyal's answer is the proper way to do things in MySQL, some of us might be working in an environment or team that requires us to use a unix timestamp instead of a datetime / timestamp.
I found that a great way to accomplish this is to use hooks inside of sequelize. At the bottom of each of your models, you can add this code:
{
tableName: 'Addresses',
hooks : {
beforeCreate : (record, options) => {
record.dataValues.createdAt = Math.floor(Date.now() / 1000);
record.dataValues.updatedAt = Math.floor(Date.now() / 1000);
},
beforeUpdate : (record, options) => {
record.dataValues.updatedAt = Math.floor(Date.now() / 1000);
}
}
}
This will insert the createdAt and updatedAt fields as unix timestamps.
No or at least not yet.
CreatedAt is set using the utils.now function in sequelize. That function uses the javascript Date function with no additional arguments. Squelize could be modified to change the way it calls Date but there is no code to do that in the current version.
see here
You could however disable the createdAt and other timestamps and use raw queries to set your own. However then you're sacrificing the functionality of sequelize.
Best solution is probably to convert those fields to unix time in your business logic before using them.
Related
In my application, a user can specify a date in a form, via a datepicker. Doing so, the date has this format : "2018-05-16T12:45:30Z".
Then, I want to store it in a MySql database, in a TIMESTAMP column.
Later, the user can edit his data. Consequently, the datepicker has to be initialized with the date coming from the server, previously saved.
To manage this, I created an accessor and a mutator :
public function setDateNameInputAttribute($value)
{
$this->attributes['date_name_input'] = Carbon::createFromFormat('Y-m-d\TH:i:s\Z', $value);
}
public function getDateNameInputAttribute($value)
{
return Carbon::parse($value)->format('Y-m-d\TH:i:s\Z');
}
This code works fine : my front-end reads UTC (Zulu) dates and I can insert timestamps in my database.
However, it's not perfect.
Let's say I need for whatever reason to add one hour to a stored date
$myObject = MyClass::find(1);
$theDate = $myObject->dateNameInput;
Now $theDate is a "T Z format" string, because of the accessor. I could recreate a Carbon object to do my addition, but I think this Carbon -> string -> Carbon transition would be ugly. How can I make a nice operation ?
If my applications contains a lot of input dates, with many different model names, is there a way to generalize my accessor and my mutator ?
Actually, is my first approach good ?
Thanks for reading !
Its confusing me. I've a property in my Model which is annotated with DateTime. In my Database its stored as timestamp. In Frontend I use the f:format.date viewhelper to output this property.
When I create a new record, and add f.e. 01.06.2017 10:00 in this field, in my database is stored the timestamp for 01.06.2017 08:00. In Frontend the output is correct. Until here everything is fine.
The last timechange in March lead to a + of two hours in output. I assume in October that will change again and the output will be than this: 01.06.2017 08:00.
How can I prevent this. Its definitely a problem when these dates change, because its important for the business.
How can I test what will happen in October?
The Problem occurs as TYPO3 saves times normalized as UTC. for normalization (and afterwards denormalization) it respects the timezone-settings of the server. Or settings given in LocalConfiguration.php.
Up to 6.2 there were two settings [SYS][serverTimeZone] and [SYS][phpTimeZone].
With 7.6 it is only [SYS][phpTimeZone] as the servertimezone is detected from php itself.
You now have the option to fake the timezone of your server to "UTC" by setting [SYS][phpTimeZone] to the string "UTC". In this way no times should be changed any more.
TYPO3 9.5 and newer
Use the environment (documentation)
// use TYPO3\CMS\Core\Utility\GeneralUtility;
// use TYPO3\CMS\Core\Context\Context;
$context = GeneralUtility::makeInstance(Context::class);
// Reading the current data instead of $GLOBALS
$currentTimezone = $context->getPropertyFromAspect('date', 'timezone');
$currentTstamp = $context->getPropertyFromAspect('date', 'timestamp');
$current = new DateTime('#'.$currentTstamp);
$current->setTimezone(new DateTimeZone($currentTimezone) );
In Fluid you may use a DateTime-Object:
// in PHP-ode of Viewhelper
//...
$this->registerArgument('date', 'mixed', 'Either an object implementing DateTimeInterface or a string that is accepted by DateTime constructor');
// ...
In HTML
{dateTimeObject -> f:format.date()}
<f:format.date format="d.m.Y">{dateTimeObject}</f:format.date>
I just started using Sails.js with its ORM, Waterline, and absolutely love it, but I am not sure how to use query modifiers for dates. I am using sails-mysql. Specifically, I am trying to get rows that have a datetime field between two specific dates. I have tried doing this:
MyModel.find()
.where({ datetime_field: { '>=': startDate } })
.where({ datetime_field: { '<=': endDate } })
.done(function(err, objects){
// ...
});
startDate and endDate are two Date objects. I have also tried converting them to strings with toString(). In both cases, I get every row from the database instead of rows between the two dates. Is there a way to do this or is this functionality not yet part of either Waterline or sails-mysql?
In the same boat (no pun intended) but using sails-mongo.
Provided you have the correct date formatting (as Jeremie mentions). I personally store dates in UTC moment(startDate).toISOString() on the client you can moment(startDate) to work in local date and time.
Looking at the Waterline source for deferred queries (see the where method) it applies the most recent datetime_field criteria it finds to be valid.
After trawling through code, searches and the group I didn't find anything that helped. I sure hope I've missed something obvious, but for now my current suggestion would be to anchor the results on your startDate and then cap it with a limit,
e.g.
.where({ datetime_field: { '>=': startDate } })
.limit(100)
You will need to format your date as a string in the YYYY-MM-DD format.
If you need help formatting your dates, moment.js has a lot of cool features for that.
formating your date would look something like
var formatedStartDate = moment(startDate).format('YYYY-MM-DD');
I have a document in CB which has two dates, a start date and an end date. Let's say, a product's price discount. 10% off starting from today and ends next Friday. How can I get all the documents from CB which have a valid discount today?
I made a view and have the following in it:
var dt = new Date();
Which gets today's date. Then I can do a simple
if(doc.FromDate < dt && doc.ToDate > dt){ emit([ ..... ]);
This filters the documents how I want. But...
Question
Is this a good approach re view and index updating? Will the index update every day because the date changed? Just trying to understand the working of CB in this respect
What is the best approach for this type of searching? If not possible please tell me!
Cheers
Robin
Note: Please note, the question is NOT like this here or this here
Let's me clarify something here:
the map() function is used to create/update the index on disk, and this occurs just "after" the document is saved on disk. This is why using date.now() in the map reduce does not really makes sense.
So what you will do is to emit the date for example emit( dateToArray(doc.startDate) );
then when you query the view(index) you can use the startkey & endkey to do a range query.
&startkey=[2013,4,16]&endkey=[2013,4,24]
the index won't be updated just because system date changed, you have to update the document. also view indexer doesn't allow you to pass any arguments defined by user. in this case you should emit the data and use date as a part of the key to filter on view query. I guess the same behaviour for SQL indexes too. you cannot predict when exactly this document will indexed, in your example you are freezing timestamp when the doc has been indexed, it isn't even the time when it was changed
Developing a component for Joomla v2.5, I'm using a table with a mysql timestamp column.
One of the component's settings is the "Timezone". I don't want to use server timezone, as code will run on different servers/timezones and I want to be indepedent. So the idea is to store timestamps in mysql, and display the correct date/time according to the component's parameter. The main drawback is the timezone that mysql server uses, that make the whole situation complicated. So, is there a way to store current timestamp in an universal format in MySQL and display it in the correct way?
The ultimate goal is for the component to be able to display the correct date/time based on the component's parameter, eg. user changes the parameter on the fly, no modification on the database take place, only on the "View"
In order to display the date in the correct timezone I use this:
JHtml::date($date_from_mysql , 'd/m/Y H:i:s', $my_component_timezone_parameter)
Please share your thoughts.
try
jimport ('joomla.utilities.date');
$date = new JDate($mydate);
$curdate = $date->toFormat('%Y-%m-%d %H:%M:%S');
for timezone settings
try http://docs.joomla.org/JDate::setTimezone/1.6
http://www.webamoeba.co.uk/site/index.php/articles-joomla-date-time
or try to override the store method in your table class:
public function store($updateNulls = false)
{
// get date
$date = JFactory::getDate();
// set variable for timestamp
$this->myDate = $date->toMySQL();
return parent::store($updateNulls);
}