I have an issue where the date fields being submitted are returning date with timestamp, rather than just the date with the timestamp set to 00:00:00. This code works for other instances where I am trying to achieve this process, but for some reason it is not working and I'm curious if the conversion has to happen within my form in my view or should happen on the back-end within my routes.
Route:
.post(function(req, res){
models.Creator.findAll({
order: 'createDate DESC',
where: {
dataDateStart: {
$gte: moment(req.body.startDate).utc().format("YYYY-MM-DD")
},
dataDateEnd: {
$lte: moment(req.body.endDate).utc().format("YYYY-MM-DD")
}
},
include: [{
model: models.User,
where: {
organizationId: req.user.organizationId,
},
attributes: ['organizationId', 'userId']
}],
limit: 10
}).then(function() {
res.redirect('/app');
}).catch(function(error){
res.send(error);
})
});
Outputted where clause:
WHERE `creator`.`data_date_start` >= '2016-06-07 04:00:00' AND `creator`.`data_date_end` <= '2016-06-11 04:00:00' ORDER BY createDate DESC LIMIT 10;
As you can see the issue is that 04:00:00 appears instead of 00:00:00
View:
<div class="row">
<div class="creator-search-form col-md-6 col-md-offset-3">
<h1 id="search-header">Filter Feed</h1>
<form action="/app" method="post" class="creator-filter-fields">
<p>Date Range:</p>
<input type="date" name="startDate">
<input type="date" name="endDate">
<button type="submit" id="creator-filter-submit">Submit</button>
</form>
</div>
</div>
I expect that what is going on in your situation is that somewhere downstream from Moment, your date without a time is being interpreted as local time, and then converted to UTC. I would guess that your server is set to UTC-4 (US Eastern Daylight?), and that is why you are seeing what you do.
When you change from using .format('YYYY-MM-DD') to just .format(), your resultant string includes all time parts and an offset, and look like this:
moment.utc('2016-01-01').format()
"2016-01-01T00:00:00Z"
Because the above date is completely unambiguous, your whatever is changing the time in your stack doesn't make any odd decisions about how to interpret it, and everything works fine.
Provided that the queried value from date elements are strings in the format YYYY-MM-DD, then you can get the result by
moment.utc(value).format("YYYY-MM-DD")
where the value is the date string.
I hope this helps.
Related
In my VueJS application I have a component with a form.
In that form I have a field to pick the date.
My requirement is to show an error message if the selected date is older than the current date.
Basically the selected date need to be either today's date or future date.
I'm using Moment JS.
I have following custom rule in my Validator.vue
const dateIsToday = (value) => {
var todayDate = moment(new Date()).format("DD-MM-YYYY");
var selectedDate = value;
return selectedDate>=todayDate;
};
But this works only if I selected an old date from the current month... Assume if the user has picked an older date from this month like 10-04-2022, then it'll show the error message.
But if the user selected an old date from last month or a past month like 10-01-2022, this won't show me the error message....
In my form.vue I have
<div class="w-1/2 mr-2">
<p class="text-certstyle-titles font-bold text-sm mb-1">Start date</p>
<div class="h-12">
<cs-date-picker
id="startDate"
v-model="project.start_date"
:default-selection="true"
:name="`${identifier}-start_at`">
</cs-date-picker>
<validator
:identifier="`${identifier}-validate-project`"
:rules="validations.startDate"
:name="`${identifier}-start_at`"
/>
</div>
</div>
And under my validations I have,
startDate: {
required: {
message: 'Project Start date is required.'
},
dateIsToday: {
message: 'Date has to be today's date or a future date.'
},
},
It seems that you are comparing strings. Instead you should make real use of moment and compare moment dates:
const dateIsToday = (value) => {
let todayDate = moment();
let selectedDate = moment(value, "DD-MM-YYYY");
return selectedDate.isSameOrAfter(todayDate);
};
I am using Vue to render some data, the problem is the date stored in the field created_at is in UTC (I need it to be in EST).
<div class="row">
<div class="col-md-3" v-for="result in results">
<div class="panel panel-default">
<div class="panel-heading">
<p>createdAt:{{ result._source.created_at }}
</div>
<div class="panel-body">
<p>text:{{ result._source.text }}</p>
</div>
</div>
</div>
</div>
I tried using this javascript variable to convert it but I'm not sure how to implement it.
<script>
var usaTime = new Date().toLocaleString("en-US", {timeZone: "America/New_York"});
console.log('USA time: '+ (new Date(usaTime)).toISOString())
</script>
Do I need to pass the value of created_at into a javascript function that will convert the date? Or could I just subtract eight hours from the date and then return it?
If you have a Date object which is in UTC, you can use your code to display it in a locale and timezone much as you did in your code.
Live demo:
var utcTime = new Date("2020-10-16T18:00:00Z");
console.log('UTC Time: ' + utcTime.toISOString());
var usaTime = utcTime.toLocaleString("en-US", {timeZone: "America/New_York"});
console.log('USA time: '+ usaTime)
So
Do I need to pass the value of created_at into a javascript function that will convert the date?
Yes, assuming your result._source.created_at value is formatted as a UTC date, you would pass it in and call toLocaleString to display it appropriately.
Perhaps something like:
<div class="panel-heading">
<p>createdAt:{{ new Date(result._source.created_at).toLocateString("en-US", {timeZone: "America/New_York") }}</p>
</div>
How can I keep updated a current date in form field? I've tried to set date at views.py and forms.py, but in that case it saves date in cache only once (when I update index.wsgi) and then it's don't update date on every page reloads. Daily restart of the app is not an option. I can't believe javascript is the only way. I'm just stuck on it, help me, please.
How it looks like now: I have a form:
class AddRecordForm(forms.ModelForm):
class Meta:
model = Journal
fields = ['date']
widgets = {
'date': forms.DateInput(attrs={'type': 'date', 'class': 'form_input', 'value': date.today().strftime("%Y-%m-%d")}),
From this model:
class Journal(models.Model):
date = models.DateTimeField()
And resulting html:
<input type="date" name="date" class="form_input" value="2020-01-17" required="" id="id_date">
Looks good, but if I go to the page tomorrow it will still be 2020-01-17. But it should be 2020-01-18 and so on. Date in form updates only after app reload (touch index.wsgi).
UPD: As it turned out, frontend way is only way. Have solved the issue in JS:
var now = new Date();
var day = ("0" + now.getDate()).slice(-2);
var month = ("0" + (now.getMonth() + 1)).slice(-2);
var today = now.getFullYear()+"-"+(month)+"-"+(day) ;
$("#id_date").val(today);
You'll need to use a frontend component
i.e A Date/Time picker as opposed to setting the value on the backend since by the time the template is rendered that date/time becomes invalid (In your case the next day).
form.py
class AddRecordForm(forms.ModelForm):
date = forms.DateTimeField(
input_formats=['%d/%m/%Y %H:%M'],
widget=forms.DateInput(
attrs={
'type': 'date',
'class': 'form_input',
},
),
)
class Meta:
model = Journal
fields = ['date']
form.html
{{ form.date.id_for_label }}
<script>
$(function () {
$("#{{ form.date.id_for_label }}").datetimepicker({
format: 'd/m/Y H:i',
});
});
</script>
I have written a small code in MeteorJS which uses Mongodb and Iron:router (I am new to MeteorJS). Everything worked fine initially and towards the end of it, sorting stopped working. To explain a little more, the list of websites must be sorted according to the upvotes it has received and date of creation. Here are the relevant sections of the code:
//Sorting websites based on userfilter or votes
websites:function(){
if (Session.get("userFilter")){
return Websites.find({ createdBy: Session.get("userFilter") }, { sort: { createdOn: -1, up: -1 }});
} else {
return Websites.find({},{ sort: { createdOn: -1, up: -1 }});
}
},
{{#each websites}}
<div class="col-xs-12 col-md-3">
<div class="thumbnail">
{{title}}
<p class="site_desc">{{description}}</p>
<br>
<p class="upvote_button">Upvote: {{up}}</p>
<p class="downvote_button">Downvote: {{down}}</p>
<a href="#" class="btn btn-default js-upvote" id="upvote_button">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</a>
<a href="#" class="btn btn-default js-downvote" id="downvote_button">
<span class="glyphicon glyphicon-arrow-down" aria-hidden="true"></span>
</a>
<br>
<p class="added-by">Added By:
{{getUser createdBy}}
</p>
<p>Added On: {{createdOn}}</p>
Details
</div>
</div>
{{/each}}
When you specify sorting according to more than one property, Mongo will sort first by the first property, then for documents that fall at the same "position", it will use your second property to order those, etc.
So you will get documents (websites) sorted by createdOn date first, and for those which have the exactly same date (including time if present), by up value. I guess this is not what you would like.
Furthermore, since you use a dictionary / mapping object type to specify your sort, you will depend on the JS engine ordering implementation. In most cases, it will order your properties by insertion order, i.e. 1) createdOn 2) up in your case.
http://docs.meteor.com/api/collections.html#sortspecifiers
The [{a: 1, b: -1}] form will only work if your JavaScript implementation preserves the order of keys in objects. Most do, most of the time, but it’s up to you to be sure.
In the end, you might have looked for this sorting:
Websites.find({}, {
sort: [
["up", "desc"], // Sort first by "up" value
["createdOn", "desc"] // then for websites with same up value, order by date
]
})
You may want ot do something like this
Websites.find({}).sort({createdOn:-1, up:-1})
Hope it works
if not try adding this
Websites.ensureIndex({createdOn: -1, up: -1})
Thanks
UPDATE:
I have added additional code for clarification, which is annotated with * NEW *.
I was asked to clarify what this code is doing. A series of data is inputted into a collection called posts. On the postsList template the code is outputted when the timeToEnable field is less than the current time, which allows us to delay posts based on a specified date using this javascript time picker. The issue I have resides in /client/posts/post_edit.js where I am trying to set the value of one of the pickers from data in the collection which I don't know how to retrieve in javascript but I do in html simply using {{fieldHere}} and using the postsList template helper.
Hopefully this new code and info helps.
ORIGINAL QIUESTION.
I have a form that submits 5 fields in a posts collection. I have a edit page that, auto populates the tile, and content. However I have two separate Date/Time pickers. There is a function available to me to properly set the Date/Time pickers with the specific posts data when I am on the edit page. I cant output Date/Time data the usual way using {{date}} because it is stored in a particular format 2015-05-25T17:50:00.000Z I have created separate fields in the collection that separates day, month, year for do so using datepicker function.
This function will allow me to set the Date picker.
picker.set('select', new Date(year, month, date));
My Issue resides in getting the year, month and date data, based on the id that the post I am editing is using. I can place them in html using {{title}}, however I don't know how I would identify the id, and grab that post in the collection, and allow me to use picker.set like above.
Here is my code that I think will explain best what I have so far.
client
/client/posts/post_submit.js
Template.postSubmit.events({
'submit form' : function(e){
e.preventDefault();
var post = {
title: $(e.target).find('[name=title]').val(),
postContent: $(e.target).find('[name="postContent"]').val(),
timeToEnable: new Date(year, month, day, hours, minutes),
timeDisplay : timeDisplay,
year : year,
month : month,
day : day,
hours : hours
};
////console.log(post.timeToEnable);
Meteor.call('postInsert', post, function(error, result) {
// display the error to the user and abort
if (error){
return alert(error.reason);
}
// show this result but route anyway
if (result.postExists){
alert('This link has already been posted');
}
Router.go('postPage', {_id: result._id});
});
}
});
/client/posts/posts_list.html * NEW *
<template name="postsList">
<div class="posts page">
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
/client/posts/post_item.html * NEW *
<template name="postItem">
{{> dashboard}}
<article>
<div class="post">
<div class="post-content">
<h1>{{title}}</h1>
<h3>{{timeDisplay}}</h3>
<p>{{{postContent}}}</p>
View
{{#if ownPost}}<a class="editPost" href="{{pathFor 'postEdit'}}">Edit</a>{{/if}}
</div>
</div>
</article>
</template>
/client/posts/posts_list.js * NEW *
Template.postsList.helpers({
posts: function() {
//return Posts.find({}, {sort: {submitted: -1}});
//
var data = new ReactiveDict();
data.set("now", new Date());
return Posts.find({timeToEnable: {$lt: data.get("now")}});
}
});
/client/posts/post_edit.html
<template name="postEdit">
{{> dashboard}}
<div class="container">
<form id="editForm">
<div class="postTitle">
<label class="titleLabel">Press Release Title.</label>
<div class="input">
<input name="title" id="title" type="text" value="{{title}}" placeholder=""/>
</div>
</div>
<div class="postTime">
<label class="titleLabel">Pick A time to post</label>
<div class="input">
<input class="timepicker" name="" id="" type="text" value="Click for a Time to Post" placeholder=""/>
</div>
</div>
<div class="postDay">
<label class="">Pick A Date to post</label>
<div class="input">
<input class="datepicker" name="" id="" type="text" value="Click for a Date to Post" placeholder=""/>
</div>
</div>
<div>
<div class="textarea">
<label class="contentLabel">Press Release content.</label>
<!-- <input name="postContent" id="postContent" type="text" value="" placeholder="Enwave has released a..."/> -->
<textarea name="postContent" id="postContent" type="text"></textarea>
</div>
</div>
<div id="submit">
<input type="submit" value="Submit"/>
</div>
<div class="deletePost">
<a class="btn btn-danger delete" href="#">Delete post</a>
</div>
</form>
</div>
</template>
This is where I want to retrieve the post fields for year, month, date. So I can set the picker to that date, all based off the specific post ID.
/client/posts/post_edit.js
This is the crucial part I need to output the fields from the collection here based on its specified id
Template.postEdit.rendered = function(){
picker.set('select', new Date(year, month, day));
}
lib
This Route outputs code to the html when using {{title}}.
/lib/router.js
Router.route('/posts/:_id/edit', {
name: 'postEdit',
data: function() { return Posts.findOne(this.params._id); }
});
lib/collections/posts.js * NEW *
Posts = new Mongo.Collection('posts');
Posts.allow({
update: function(userId, post) { return ownsDocument(userId, post); },
remove: function(userId, post) { return ownsDocument(userId, post); },
});
Posts.deny({
update: function(userId, post, fieldNames) {
// may only edit the following two fields:
return (_.without(fieldNames, 'title', 'postContent','timeToEnable','timeDisplay','year','month','day','hours').length > 0);
}
});
Meteor.methods({
postInsert: function(postAttributes) {
check(Meteor.userId(), String);
check(postAttributes, {
title: String,
postContent: String,
timeToEnable: Date,
timeDisplay:String,
year: Number,
month: Number,
day: Number,
hours: Number
});
var user = Meteor.user();
var post = _.extend(postAttributes, {
userId: user._id,
author: user.username,
submitted: new Date()
});
var postId = Posts.insert(post);
return {
_id: postId
};
}
});
server
~/server/publications.js`
Meteor.publish('posts', function() {
return Posts.find();
});
So I would like to grab the collection fields for posts into postEdit when the template is rendered, which will set the value of day input picker.
Thanks for help in advance.
This is what ended up working for me in the end.
client
/posts/post_edit.js
Template.post_edit.rendered = function(){
var year = (postObject.year);
var month = (postObject.month) -1;
var day = (postObject.day);
var hours = (postObject.hours);
var $input = $('.datepicker').pickadate();
var $inputTime = $('.timepicker').pickatime();
// Use the picker object directly.
var picker = $input.pickadate('picker');
var pickerTime = $inputTime.pickatime('picker');
picker.set('select', new Date(year, month, day));// Get on screen image
pickerTime.set('select', [hours,0]);// Get on screen image
}
lib
/lib/router.js
Router.route('/posts/:_id/edit', {
name: 'postEdit',
data: function() {
postObject = Posts.findOne(this.params._id);
return postObject;
}
});