Wrong date with moment JS plugins - momentjs

Trying to generate 15 days advance date using moment JS but it doesnt starts with today's date but the day before.
console.log( "Today's date : " + d1.getDate().toString())
for (i = 1; i <= 15; i++) {
console.log(moment(d1).day(i, 'd').format('MM/DD/YYYY') )
selectDt.append($("<option></option>")
.attr("value", moment(d1).day(i,'d').format('MM/DD/YYYY'))
.text(moment(d1).day(i,'d').format('MMM-DD,YYYY'))
.prop("selected", (selval != undefined) ? (moment(d1).day(i,'d').format('MMM-DD,YYYY') == selval) : '')
)
}
Result is,

My solution is to use the moment add method for getting after 15 dates. If you want before 15 use the moment subtract method.
For your code with my changes.
console.log( "Today's date : " + d1.getDate().toString())
for (i = 0; i <= 15; i++) {
console.log(moment(d1).add(i, 'd').format('MM/DD/YYYY') )
selectDt.append($("<option></option>")
.attr("value", moment(d1).add(i,'d').format('MM/DD/YYYY'))
.text(moment(d1).add(i,'d').format('MMM-DD,YYYY'))
.prop("selected", (selval != undefined) ? (moment(d1).day(i,'d').format('MMM-DD,YYYY') == selval) : '')
)
}
My working code
var d1 = new Date();
console.log( "Today's date : " + d1.getDate().toString())
for (i = 0; i <= 15; i++) {
console.log(moment(d1).add(i, 'day').format('MM/DD/YYYY') )
}
My Output

Related

Last line of a datatable asp.net

I have a problem when I'm trying to a loop in a DataTable that a dataset contains.
I'm doing a loop like this:
for(int i = 0; i<ds.Tables[0].Rows.Count - 1 ; i++)
The problem is that I can't get the value of the last line with this one, but if I try to get rid of the "-1" and do a loop on the whole table, I'll have an out of range exception.
This out of range exception is because I have to check if the value of a line "i" is equal to the value of a line "i+1", like this:
if (ds.Tables[0].Rows[i]["Release_No"] != ds.Tables[0].Rows[i + 1]["Release_No"])
So if I do it in a loop, when the index is on the last line it will check if the last line is equal to i+1, and it's out of the table.
So I was trying to check if the index is on the last line, then just get the value of the last line, but it seems like it doesn't work.
if(ds.Tables[0].Rows.IndexOf(ds.Tables[0].Rows[i]) == ds.Tables[0].Rows.Count)
If anyone has an idea, let me know, and of course if it is not clear enough let me know, I'll give more information and more code.
Thanks for your help and your time!
Check if it's the last record, first.
I like to refactor code to read as close to sentence form as possible, explaining what you want it to do using named variables and methods, and that often gets me unlocked.
Try to make each line of code do one thing, and one thing only, like check if it is the last row:
var data = ds.Tables[0].Rows;
var lastRow = data.Count - 1;
for(int i = 0; i < lastRow ; i++)
{
if (i == lastRow){
// This is the last row. Handle the last row here.
}
else
{
// Handle all other rows here
var currentRecord = data[i];
var nextRecord = data[i + 1];
if (currentRecord["Release_No"] != nextRecord["Release_No"])
{
// Handle unique Releases...
}
}
}
Use less than or equal to like this
for(int i = 0; i<=ds.Tables[0].Rows.Count - 1 ; i++)
I hope this may get what you want.
Something like this is better ?
var lastRow = data.Count - 1;
var data = ds.Tables[0].Rows;
for(int i = 0; i< lastRow; i++)
{
testFirstCum = Convert.ToInt32(ds.Tables[0].Rows[i]["EDI_Accum_Quantity"]);
if ( i == lastRow)
{
if (DBNull.Value.Equals(data[i]))
{
quantity = 0;
}
else
{
quantity = Convert.ToInt32(data[i]);
testFirstCum = testFirstCum + quantity;
System.Diagnostics.Debug.WriteLine(quantity);
System.Diagnostics.Debug.WriteLine(testFirstCum);
}
}
else
{
var col = ds.Tables[0].Columns;
var currentRecord = data[i];
var nextRecord = data[i + 1];
if(currentRecord["Release_No"] != nextRecord["Release_No"])
{
for (int j = col[2].Ordinal; j < col.Count; j++)
{
if (DBNull.Value.Equals(data[i][j]))
{
quantity = 0;
}
else
{
quantity = Convert.ToInt32(data[i][j]);
testFirstCum = testFirstCum + quantity;
System.Diagnostics.Debug.WriteLine(quantity);
System.Diagnostics.Debug.WriteLine(testFirstCum);
}
}
}
}
}

ASP.Net data table to excel shows date time format issue

When am creating excel from datatatble in asp.net date time format is wrong. I just convert date time to 'dd-MM-yyyy', if the date is greater than 12 , it would write correctly , otherwise it would be mm-dd-yyyy format. Actuall am writing '01-11-2016' ie November 1st, but it shows '11-01-2016' in excel. My code is like this. Give me a solution.
int rowsTotal = 0, colsTotal = 0;
int i, j, k;
rowsTotal = dt.Rows.Count;
colsTotal = dt.Columns.Count;
for (i = 0; i <= rowsTotal - 1; i++)
{
k = 0;
for (j = 0; j <= colsTotal - 1; j++)
{
if (gv. Columns[j].Visible)
{
if (dt.Columns[j].DataType.Name == "DateTime")
{
DateTime dtDate = new DateTime();
excelWorksheet.Cells[i + 4, k + 1] = string.Format("{0:dd-MM-yyyy}", dt.Rows[i][j] != DBNull.Value ? Convert.ToDateTime(dt.Rows[i][j]) : dt.Rows[i][j]);
}
else
{
excelWorksheet.Cells[i + 4, k + 1] = dt.Rows[i][j];
}
k += 1;
}
}
}

how to load previous month name in dropdown using c#

private void GenerateMonth(bool SetCurruntMonth)
{
drpMonth.Items.Clear();
int year = drpYear.SelectedIndex != 0 ? ((drpYear.SelectedValue != "") ? Convert.ToInt32(drpYear.SelectedValue) : DateTime.Now.Year)
: DateTime.Now.Year;
int months = (DateTime.Now.Year == year) ? DateTime.Now.Month : 12;
for (int i = 1; i <= months; i++)
{
drpMonth.Items.Add(new ListItem(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i), i.ToString()));
}
if (SetCurruntMonth == true && DateTime.Now.Year == year)
{
drpMonth.Items.FindByValue(DateTime.Now.AddMonths(-1).ToString()).Selected = true;
}
else
{
drpMonth.SelectedIndex = 0;
}
}
Your method should look like this:
private void GenerateMonth(bool SetCurruntMonth, DateTime currentDate)
{
drpMonth.Items.Clear();
int year = drpYear.SelectedIndex != 0 ? ((drpYear.SelectedValue != "") ? Convert.ToInt32(drpYear.SelectedValue) : currentDate.Year)
: currentDate.Year;
//int months = (currentDate.Year == year) ? currentDate.Month : 12;
int months = 12;
for (int i = 1; i <= months; i++)
{
drpMonth.Items.Add(new ListItem(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i), i.ToString()));
}
if (SetCurruntMonth == true && currentDate.Year == year)
{
if (currentDate.Month > 1)
drpMonth.Items.FindByValue(currentDate.AddMonths(-1).Month.ToString()).Selected = true;
else
drpMonth.Items.FindByValue("1").Selected = true;
}
else
{
drpMonth.SelectedIndex = 0;
}
}
The problem was you weren't checking the Month property when you were attempting to select it in the dropdownlist. Instead you were checking the full datetime value.
Edit: I've fixed your issue but I've also just added an extra date parameter to make it easier to test, you can replace this if you'd like.
Edit 2: Commented out 'Month' logic so that all months appear in the dropdown list.
private void GenerateMonth(bool SetCurruntMonth, DateTime currentDate)
{
drpYear.ClearSelection();
drpMonth.Items.Clear();
int year = drpYear.SelectedIndex != 0 ? ((drpYear.SelectedValue != "") ? Convert.ToInt32(drpYear.SelectedValue) : currentDate.Year) : currentDate.Year;
int months = (currentDate.Year == year) ? currentDate.Month : 12;
int i;
for ( i = 1; i <= 12; i++)
{
drpMonth.Items.Add(new ListItem(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(i), i.ToString()));
}
//int month;
if (SetCurruntMonth == true && currentDate.Year == year)
{
if (currentDate.Month >= 1)
{
drpMonth.Items.FindByValue(currentDate.AddMonths(-1).Month.ToString()).Selected = true;
// month = Convert((currentDate.AddMonths(-1).Month.ToString()).Selected = true);
}
else
drpMonth.Items.FindByValue("1").Selected = true;
//drpYear.Items.FindByValue((DateTime.Now.Year-1).ToString()).Selected = true;
if (currentDate.Month == 1)
{
DateTime year1 = (currentDate.AddYears(-1));
int yy = Convert.ToInt16(year1.Year);
enter code here
drpYear.Items.Add(new ListItem(Convert.ToString(year)));
drpYear.SelectedValue= Convert.ToString(yy);
}
}
else
{
drpMonth.SelectedIndex = 0;
}
}

Need assistance with recursion in JS

I'm having a great deal of trouble wrapping my head around recursion. Simple recursion I can do but this is one is not easy for me. My goal here is to speed up this search algorithm. I'm guessing recursion will help. It takes 15 seconds on a simple 43 node tree with children as it is. Below is my unrolled recursion fomr of the code that works.
var nodeList = new Array();
var removeList = new Array();
var count = 0;
var foundInThisNodeTree;
var find = function ( condition )
{
}
while ( this.treeIDMap.igTree( "nodeByPath", count ).data() )
{
var foundInThisNodeTree = false;
var n;
n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count ) )
if ( n.data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; }
else {//look deeper
var i = 0;
while ( this.treeIDMap.igTree( "nodeByPath", count + "_" + i ).data() )
{
n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count + "_" + i ) );
if ( n.data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
else {//look deeper
var j = 0;
while ( this.treeIDMap.igTree( "nodeByPath", count + "_" + i + "_" + j ).data() )
{
n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count + "_" + i + "_" + j ) );
if ( n.data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
else {//look deeper
var k = 0;
while ( this.treeIDMap.igTree( "nodeByPath", count + "_" + i + "_" + j + "_" + k ).data() )
{
n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count + "_" + i + "_" + j + "_" + k ) );
if ( n.data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
k++;
}
}
j++;
}
}
i++;
}
}
if ( !foundInThisNodeTree ) this.treeIDMap.igTree("removeAt", ""+count )
else count++;
}
*** second revision suggested by Mirco Ellmann *****
var nodeList = new Array();
var removeList = new Array();
var count = 0;
var foundInThisNodeTree;
filter = filter.toLowerCase();
while ( this.treeIDMap.igTree( "nodeByPath", count ).data() )
{
var foundInThisNodeTree = false;
var n;
n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count ) )
if ( n.data.ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; }
else {//look deeper
var i = 0;
n = this.treeIDMap.igTree( "childrenByPath", count );
while ( n[i] )
{
if ( n[i].data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
var j = 0;
n = this.treeIDMap.igTree( "childrenByPath", count + "_" + i );
while ( n[j] )
{
if ( n[j].data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
var k = 0;
n = this.treeIDMap.igTree( "childrenByPath", count + "_" + i + "_" + j);
while ( n[k] )
{
if ( n[k].data.ITEM.indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
k++;
}
j++;
}
i++;
}
}
if ( !foundInThisNodeTree ) this.treeIDMap.igTree("removeAt", ""+count )
else count++;
}
****using my branchable trees to get the data no need for any calls to tree****
var count = 0;
var foundInThisNodeTree;
filter = filter.toLowerCase();
while ( this.treeIDMap.igTree( "nodeByPath", count ).data() )
{
var foundInThisNodeTree = false;
var n;
n = this.treeIDMap.igTree( "nodeFromElement", this.treeIDMap.igTree( "nodeByPath", count ) )
if ( n.data.ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; }
if ( n.data.branch )//look at all childer under the root node
{
var i = 0;
n = n.data.branch;
while ( n[i] )//look at all childer under the root node
{
if ( n[i].ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
while ( n[i].branch )//look deeper
{
var j = 0;
n = n[i].branch;
if ( n[j].ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
while ( n[j].branch )//look deeper
{
var k = 0;
n = n[j].branch;
if ( n[k].ITEM.toLowerCase().indexOf( filter ) > -1 ) { foundInThisNodeTree = true; break; }
k++;
}
j++;
}
i++;
}
}
if ( !foundInThisNodeTree ) this.treeIDMap.igTree("removeAt", ""+count )
else count++;
}
instead of always use "nodeByPath" you should use "childrenByPath".
that would minimize the search calls on the igTree.
PS: USE not REPLACE ;)
You're not really doing this recursively. You're rather repeating your code for each level in the hierarchy. What you want is a helper function which takes the current node-path as a parameter and recursively calls the same method for each of its children with their id added to the path of the current node. Recursively means the code should work for any depth of tree. To me it looks like your code will only work for a set depth.
For the speed issue, there might be two issues. I didn't really read your code too closely, so I leave it to you to figure out which one is more likely.
You might be revisiting nodes. If so, obviously that would impact performance.
The framework you're using might be slow with looking up the nodes. One solution could be to find alternate methods to call on the framework which is meant for what you're doing. For instance the framework might have a hierarchical representation internally, but has to rebuild it or parse it when you pass in your full paths. Look for methods taking a source and relative path instead. If that's not the problem the framework might just be slow, and you might be better of to read all the nodes and build your own in-memory tree to use instead.
ok, I found a way to use the data provider and use a normal Json search. Still if anyone can speed this up I'd be grateful. I just when from 15 seconds to 1. This one has the recursion I need.
findInObject = function( obj, prop, val )
{
if ( obj !== null && obj.hasOwnProperty( prop ) && obj[prop].toLowerCase().indexOf(val) > -1 )
{
return obj;
} else
{
for ( var s in obj )
{
if ( obj.hasOwnProperty( s ) && typeof obj[s] == 'object' && obj[s] !== null )
{
var result = findInObject( obj[s], prop, val );
if ( result !== null )
{
return result;
}
}
}
}
return null;
}
for ( var i = 0; i < this.treeData.length; i++)
{
if ( findInObject( this.treeData[i], "ITEM", filter ) ) foundNodes.push( this.treeData[i] )//does the node have a match?
}
this.treeIDMap.igTree( { dataSource: foundNodes } );
this.treeIDMap.igTree( "dataBind" );
};

Full humanized durations in moment.js

I tried this in moment.js
moment.duration(375,'days').humanize()
and get "a year" as answer, but I would expect "a year and 10 days". Is there a way in moment.js to get the full humanized value?
Moment.js is providing the fromNow function to get time durations in human readable fromat, see http://momentjs.com/docs/#/displaying/fromnow/
Example:
moment([2007, 0, 29]).fromNow(); // 4 years ago
moment().subtract(375, 'days').fromNow(); // a year ago
You need to use third party lib as suggested by #Fluffy
I found this small lib, that only display duration (if you don't really need all the features of moment.js)
https://github.com/EvanHahn/HumanizeDuration.js
Try this plugin:
https://github.com/jsmreese/moment-duration-format
moment.duration(123, "minutes").format("h [hrs], m [min]");
// "2 hrs, 3 min"
I was looking at the same issue and seems like there is no plan on supporting this in the future...
Although one workaround proposed is to make an language definition that overrides default implementation of humanized messages:
https://github.com/timrwood/moment/issues/348
Kind of an overkill if you ask me...
Use moment.relativeTimeThreshold('y', 365) to set the rounding.
moment.relativeTimeThreshold('s', 60);
moment.relativeTimeThreshold('m', 60);
moment.relativeTimeThreshold('h', 24);
moment.relativeTimeThreshold('d', 31);
moment.relativeTimeThreshold('M', 12);
moment.relativeTimeThreshold('y', 365);
I made a function to solve this exact problem.
function formatDuration(period) {
let parts = [];
const duration = moment.duration(period);
// return nothing when the duration is falsy or not correctly parsed (P0D)
if(!duration || duration.toISOString() === "P0D") return;
if(duration.years() >= 1) {
const years = Math.floor(duration.years());
parts.push(years+" "+(years > 1 ? "years" : "year"));
}
if(duration.months() >= 1) {
const months = Math.floor(duration.months());
parts.push(months+" "+(months > 1 ? "months" : "month"));
}
if(duration.days() >= 1) {
const days = Math.floor(duration.days());
parts.push(days+" "+(days > 1 ? "days" : "day"));
}
if(duration.hours() >= 1) {
const hours = Math.floor(duration.hours());
parts.push(hours+" "+(hours > 1 ? "hours" : "hour"));
}
if(duration.minutes() >= 1) {
const minutes = Math.floor(duration.minutes());
parts.push(minutes+" "+(minutes > 1 ? "minutes" : "minute"));
}
if(duration.seconds() >= 1) {
const seconds = Math.floor(duration.seconds());
parts.push(seconds+" "+(seconds > 1 ? "seconds" : "second"));
}
return "in "+parts.join(", ");
}
This function takes a period string (ISO 8601), parses it with Moment (>2.3.0) and then, for every unit of time, pushes a string in the parts array. Then everything inside the parts array gets joined together with ", " as separation string.
You can test it here: https://jsfiddle.net/mvcha2xp/6/
I'm using it as a Vue filter to humanize durations correctly.
This issue on Github contains a lot of discussion about exactly that. Many are asking for a more precise humanized option.
Chime in with why you need it, use cases, etc.
https://github.com/moment/moment/issues/348
i have written this javascript code to humanize the duration,
function humanizeDuration(timeInMillisecond) {
var result = "";
if (timeInMillisecond) {
if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24 * 30 * 12))) > 0) {//year
result = result === 1 ? result + " Year" : result + " Years";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24 * 30))) > 0) {//months
result = result === 1 ? result + " Month" : result + " Months";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60 * 24))) > 0) {//days
result = result === 1 ? result + " Day" : result + " Days";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60 * 60))) > 0) {//Hours
result = result === 1 ? result + " Hours" : result + " Hours";
} else if ((result = Math.round(timeInMillisecond / (1000 * 60))) > 0) {//minute
result = result === 1 ? result + " Minute" : result + " Minutes";
} else if ((result = Math.round(timeInMillisecond / 1000)) > 0) {//second
result = result === 1 ? result + " Second" : result + " Seconds";
} else {
result = timeInMillisecond + " Millisec";
}
}
return result;
}
One of the solutions:
function getCountdown() {
// diff in seconds, comes through function's params
const diff = 60*60*24*4 + 60*60*22 + 60*35 + 5;
const MINUTE = 60;
const HOUR = MINUTE * 60;
const DAY = HOUR * 24;
const days = Math.floor(diff / DAY);
const hDiff = diff % DAY;
const hours = Math.floor(hDiff / HOUR);
const mDiff = hDiff % HOUR;
const minutes = Math.floor(mDiff / MINUTE);
const seconds = mDiff % MINUTE;
return [days, hours, minutes, seconds]
.map(v => (''+v)[1] ? ''+v : '0'+v)
}
output: ["04", "22", "35", "05"]
I needed it up to days only, but can be easily extended to weeks.
Doesn't make sense with months since diff says nothing about start date.
Having a period split to parts, adding "days"/"hours"/... is obvious.
Moment.js provides:
var y = moment.duration(375,'days').years(); // returns 1
var d = moment.duration(375,'days').days(); // returns 9
var data = y + 'y ' + d + 'd';
console.log(data);
This could be used with a bit of extra logic
This is my solution on CoffeeScript:
humanizeDuration = (eventDuration)->
eventMDuration = Moment.duration(eventDuration, 'seconds');
eventDurationString = ""
if (eventMDuration.days() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.days(), 'days').humanize()
if (eventMDuration.hours() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.hours(), 'hours').humanize()
if (eventMDuration.minutes() > 0)
eventDurationString += " " + Moment.duration(eventMDuration.minutes(), 'minutes').humanize()
eventDurationString.trim()
This is my solution, I like it better than the others here:
val moment1 = moment();
val moment2 = mement();
console.log(moment.duration(moment1.diff(moment2)).humanize());
Based on Ihor Kaslashnikov's solution, I modified the function to be even more accurate using vanilla Javascript.
function momentHumanize(eventDuration, unit) {
var eventMDuration = moment.duration(eventDuration, unit);
var eventDurationArray = [];
if (eventMDuration.years() > 0) {
eventDurationArray.push(eventMDuration.years() + ' years');
eventMDuration.subtract(eventMDuration.years(), 'years')
}
if (eventMDuration.months() > 0) {
eventDurationArray.push(eventMDuration.months() + ' months');
eventMDuration.subtract(eventMDuration.months(), 'months')
}
if (eventMDuration.weeks() > 0) {
eventDurationArray.push(eventMDuration.weeks() + ' weeks');
eventMDuration.subtract(eventMDuration.weeks(), 'weeks')
}
if (eventMDuration.days() > 0) {
eventDurationArray.push(eventMDuration.days() + ' days');
eventMDuration.subtract(eventMDuration.days(), 'days')
}
if (eventMDuration.hours() > 0) {
eventDurationArray.push(eventMDuration.hours() + ' hours');
eventMDuration.subtract(eventMDuration.hours(), 'hours')
}
if (eventMDuration.minutes() > 0) {
eventDurationArray.push(eventMDuration.minutes() + ' minutes');
}
return eventDurationArray.length === 1 ? eventDurationArray[0] :
eventDurationArray.join(' and ')
}
This will remove any amount from the moment instance once it humanizes it.
I did this because Ihor's solution was inaccurate, given that moment's humanize function rounds the value. For example, if I had 2.8 hours, it should've been 2 hours and an hour.
My solution removes the 2 hours, from the instance, leaving only 0.8 hours, and doesn't use moment's humanize function to avoid rounding.
Examples:
momentHumanize(45, 'minutes') // 45 minutes
momentHumanize(4514, 'minutes') // 3 days and 3 hours and 14 minutes
momentHumanize(45145587, 'minutes') // 85 years and 10 months and 1 days and 2 hours and 27 minutes
var s=moment([2020, 03, 29]).subtract(3, 'days').fromNow();
document.write(s)
enter link description here

Resources