I have this as my date: 1212009 so this should be like 12/1/2009 but I am stuck this as an id field and id fields cannot have dashes in there names.
Now can java-script take this number and re add the slashed in for me or how would I go about doing this?
Thanks
You should have two-digit numbers for the month and day, since "1212009" is ambiguous, could be interpreted as "1/21/2009" or "12/1/2009".
If you add the leading zeros, you know that there will be always 8 digits, so you can do something like this:
var str = "12012009"
var result = str.replace(/(\d{2})(\d{2})(\d{4})/, "$1/$2/$3");
// 12/01/2009
Or
var result = str.match(/(\d{2})(\d{2})(\d{4})/).slice(1).join('/');
// 12/01/2009
Well without leading zeros, it's not possible to make a reliable conversion. It's impossible to know if 1232009 is 1/23/2009 or 12/3/2009 without leading zeros. Also, your example number could be interpreted as 1/21/2009 too.
All you need to do is pass the string into the new date constructor.
Here is a good javascript resource for you to look at.
http://www.javascriptkit.com/jsref/date.shtml
Assuming that you add the leading zeroes to remove the ambiguity, you can format the date like so:
dateString = String(id).match(/(\d{2})(\d{2})(\d{4})/).slice(1).join('/')
Maybe this will help you to get rid of the six or seven numbers long date (most important part is the first part):
var sDate = "1212009";
if(sDate.length == 7){
sDate = sDate.substr(0,2) + "0" + sDate.substr(2);
}
else if(sDate.length == 6){
sDate = "0" + sDate.substr(0,1) + "0" + sDate.substr(1);
}
// This part can be done with Regular Expressions, as shown in other comments
var month = parseInt(sDate.substring(0,2));
var day = parseInt(sDate.substring(2,4));
var year = parseInt(sDate.substring(4));
alert(day + "/" + month + "/" year);
// Will alert 12/1/2009
However,
1232009 will always be 01/23/2009, not 12/03/2009
112009 changes to 1/1/2009
10102009 changes to 10/10/2009
Related
I have a date column and need to be able to both sort and filter on it. The data comes in as strings like 2010-12-23 and can pre-processed as needed. It should be shown as 23.12.2010. Some internationalization will come later.
I wonder what's the proper internal representation:
a string like "23.12.2010" is bad for sorting (it could be done by sorting on function result, but it'd be slow)
a string like "2010-12-23" sorts correctly, can be formatted easily, but filtering for 23.12 does not work (it could be done, but it'd be slow)
Date would probably get sorted correctly, but filtering would be slow
moment could be the solution, no idea
My current idea is to create an object containing both milliseconds and the displayed string, so that all operations can be fast. But I'd bet that someone was that smart before me....
Let's assume that showing dates in the form like 2010-12-23 is unacceptable, otherwise the problem is solved. To summarize, the problem is that I need to
display and filter in the DD.MM.YYYY format
sort according to the numerical value (or equivalently, as if it was in th ISO format).
I think the method you're proposing wouldn't run in to too many performance issues, unless you're going for really old browsers or mobile devices.
I've mocked up an example to do a quick (performance) test. First, I'm defining an object that holds a value optimized for sorting, and a value optimized for display:
var MyDate = function(dateString) {
var date = new Date(dateString);
var displayValue = "{0}.{1}.{2}"
.replace("{0}", prefixZeroIfNeeded(date.getUTCDate()))
.replace("{1}", prefixZeroIfNeeded(date.getUTCMonth() + 1))
.replace("{2}", date.getUTCFullYear());
return {
sortKey: date.getTime(),
displayValue: displayValue
};
};
The prefixZeroIfNeeded method ensures we get the DD.MM format rather than the dd.mm one:
var prefixZeroIfNeeded = function(nr) {
return nr < 10 ? "0" + nr : "" + nr;
};
Then, we need some data to convert:
var data = [];
var myDates = data
.map(MyDate)
.sort(function(date1, date2) {
return date1.sortKey - date2.sortKey;
});
Finally, a quick example of a very basic search function:
var searchMyDates = function(str) {
return myDates.filter(function(myDate) {
return myDate.displayValue.indexOf(str) !== -1;
});
};
Now, we can create some mockup data and check how long it would actually take to A) map and sort the raw strings to the MyDate objects, and B) search for a string in our collection.
Here's how I generated the raw data:
for (var i = 0; i < 10000; i += 1) {
var y = Math.floor(Math.random() * 101) + 1900;
var m = prefixZeroIfNeeded(Math.floor(Math.random() * 13));
var d = prefixZeroIfNeeded(Math.floor(Math.random() * 29));
data.push(y + "-" + d + "-" + m);
}
Using console.time to measure, processing the data on my machine (A) takes around 40ms. Searching for the string .12. takes around 5-10ms.
Concluding: I think you were definitely on the right track and could continue work in the proposed direction. However, in my personal experience, I've learned that whenever I start work on a feature that involves dates and times, moment.js is the way to go. You'll eventually run in to daylight saving time, time zones, you name it and regret you thought it was simple...
Let me know if this is of any help.
Edit: the code in a snippet (check your browser console for output)
var data = [];
var prefixZeroIfNeeded = function(nr) {
return nr < 10 ? "0" + nr : "" + nr;
};
// Generate random data:
for (var i = 0; i < 10000; i += 1) {
var y = Math.floor(Math.random() * 101) + 1900;
var m = prefixZeroIfNeeded(Math.floor(Math.random() * 13));
var d = prefixZeroIfNeeded(Math.floor(Math.random() * 29));
data.push(y + "-" + d + "-" + m);
}
var MyDate = function(dateString) {
var date = new Date(dateString);
var displayValue = "{0}.{1}.{2}"
.replace("{0}", prefixZeroIfNeeded(date.getUTCDate()))
.replace("{1}", prefixZeroIfNeeded(date.getUTCMonth() + 1))
.replace("{2}", date.getUTCFullYear());
return {
sortKey: date.getTime(),
displayValue: displayValue
};
};
console.time("Map and sorting");
var myDates = data
.map(MyDate)
.sort(function(date1, date2) {
return date1.sortKey - date2.sortKey;
});
var searchMyDates = function(str) {
return myDates.filter(function(myDate) {
return myDate.displayValue.indexOf(str) !== -1;
});
};
console.timeEnd("Map and sorting");
console.time("Search");
console.log("Searching for the month 12, %d results.", searchMyDates(".12.").length);
console.timeEnd("Search");
This may help you a bit. I have used the same thing working with React. Here is a link for Moment.js -
http://momentjs.com/docs/#/displaying/format/
If you go under Display -> Format on the right menu bar, you'll see localized formats, you will need to use format L - pre defined format from moment which will show you 09/04/1986 (September 4, 1986); otherwise you can create your own using DD-MM-YYYY format.
For Example, The way I used in React for my exercise is
To define a variable using let:
let deadlineFormated = Moment(this.props.ToDoItem.deadline).format('llll');
Hope this helps for Angular!
Gist: Decouple sorting and filtering. Do sorting on the internal representation and filtering on the presentation.
Sort on internal representation that is in any naturally sortable format. Your raw YYYY-MM-DD date strings would work, so would parsing them into Date objects. The performance difference could be negligible unless you're dealing with lots and lots of rows -- but in that case you would already have other issues with latency and rendering performance.
It's more intuitive if free-text filtering is done on what's displayed (the presentation). So if you're formatting the dates as "May 7, 2016", do a substring match on that. If you're formatting the dates as DD.MM.YYYY, do a substring match on that.
If filtering is driven by actual date selections from controls like a date picker or a select field, you can do the filtering on the internal representation.
Try with this:
Get Unixtimestamp for date (i.e. Numeric format) and use jquery sort.
Please check this example for jquery sort. Regarding example replace your unixtimestamp to value.
<ul id="datelist">
<li value="1360013296">Date 1</li>
<li value="1360013297">Date 2</li>
<li value="1360013298">Date 3</li>
<li value="1360013299">Date 4</li>
</ul>
https://jsfiddle.net/ajaygokhale/bohgoq8o/
To reliably implement sorting converting it into a Date Object is recommended (new Date(str))
If you need to be flexible in formatting moment has formatting support (check moment.format()) as well. Moment has pretty deep locale support as well.
You can always keep it a Date Object as the source of truth and for filtering you could do Date.toString() just at the time of filtering. This returns a string you could then filter with.
I am developing using fullcalendar.js, and in the week view, when a week is from 2 different months (for example 27 july - 2 august) the fullcalendar week view shows the two months text. I am searching everywhere but there is no solution for this. Maybe stackoverflow users can help me.
That's what I have:
And that's what I need:
I see the date format but is MMMM YYYY, and it returns two months or one automatically and it seems impossible to change this.
In Calendar.defaults (aprox. line 8300 in non-minimized code) object I can notice this:
titleRangeSeparator: ' \u2014 ', // emphasized dash
monthYearFormat: 'MMMM YYYY', // required for en. other languages rely on datepicker computable option
As I explained, monthYearFormat seems to only be one month, but in a specific moment it merges with titleRangeSeparator to become two months.
Do you know how this is solvable?
Thank you.
EDIT
I found the functions that make this complex string, but is used by month and day views that I don't want to change (I need only to week view). The code is the next. How can I modify this code to solve it?
// Date Range Formatting
// -------------------------------------------------------------------------------------------------
// TODO: make it work with timezone offset
// Using a formatting string meant for a single date, generate a range string, like
// "Sep 2 - 9 2013", that intelligently inserts a separator where the dates differ.
// If the dates are the same as far as the format string is concerned, just return a single
// rendering of one date, without any separator.
function formatRange(date1, date2, formatStr, separator, isRTL) {
var localeData;
date1 = fc.moment.parseZone(date1);
date2 = fc.moment.parseZone(date2);
localeData = (date1.localeData || date1.lang).call(date1); // works with moment-pre-2.8
// Expand localized format strings, like "LL" -> "MMMM D YYYY"
formatStr = localeData.longDateFormat(formatStr) || formatStr;
// BTW, this is not important for `formatDate` because it is impossible to put custom tokens
// or non-zero areas in Moment's localized format strings.
separator = separator || ' - ';
return formatRangeWithChunks(
date1,
date2,
getFormatStringChunks(formatStr),
separator,
isRTL
);
}
fc.formatRange = formatRange; // expose
function formatRangeWithChunks(date1, date2, chunks, separator, isRTL) {
var chunkStr; // the rendering of the chunk
var leftI;
var leftStr = '';
var rightI;
var rightStr = '';
var middleI;
var middleStr1 = '';
var middleStr2 = '';
var middleStr = '';
// Start at the leftmost side of the formatting string and continue until you hit a token
// that is not the same between dates.
for (leftI=0; leftI<chunks.length; leftI++) {
chunkStr = formatSimilarChunk(date1, date2, chunks[leftI]);
if (chunkStr === false) {
break;
}
leftStr += chunkStr;
}
// Similarly, start at the rightmost side of the formatting string and move left
for (rightI=chunks.length-1; rightI>leftI; rightI--) {
chunkStr = formatSimilarChunk(date1, date2, chunks[rightI]);
if (chunkStr === false) {
break;
}
rightStr = chunkStr + rightStr;
}
// The area in the middle is different for both of the dates.
// Collect them distinctly so we can jam them together later.
for (middleI=leftI; middleI<=rightI; middleI++) {
middleStr1 += formatDateWithChunk(date1, chunks[middleI]);
middleStr2 += formatDateWithChunk(date2, chunks[middleI]);
}
if (middleStr1 || middleStr2) {
if (isRTL) {
middleStr = middleStr2 + separator + middleStr1;
}
else {
middleStr = middleStr1 + separator + middleStr2;
}
}
return leftStr + middleStr + rightStr;
}
This isn't directly supported unfortunately, but there is still a better way than modifying the FC source (that get's messy with patches and stuff).
There are several render hooks available that we can use to fix the formatting after the fact. viewRender doesn't work because it's called before the title changes. So we can use eventAfterAllRender instead.
eventAfterAllRender:function(){
if(view.name!=="agendaWeek")
return;
var $title = $("#calendar").find(".fc-toolbar h2"); //Make sure this is the right selector
var text = $title.text();
text = text.match(/.*? /)+text.match(/[0-9]+/);
$title.text(text); //replace text
}
JSFiddle - titleFormat hack
Not the most elegant thing in the world, but it should work better than modifying the source. Let me know if there are any issues.
Edit:
Also, if you're having problems with it flashing the wrong dateformat before the correct one, use css the make the title invisible. Then add a class to the element in eventAfterAllRender that makes it visible again.
Currently, I am pulling in a json feed from our calendar. It brings back the date in the yyyy/mm/dd format... I know I can overwrite this format by using javascript but how would I do this? I need the output to only be the "dd" not the month nor the year.
I would also like single digit days to show up as i.e. "1","2","3","4" and of course dbl digits to show up as usual "10", "11", "12", etc. Any ideas on how I could achieve this reformatting of the date via javascript/jquery?
You can use a Date object
var theDate = new Date(dateString);
var theDay = parseInt(theDate.getDate(), 10);
Alternatively, if you don't want to use the object and can expect the same string back each time:
var theDay = parseInt(dateString.split('/')[2], 10);
This code should do it . . .
var jsonDate = <...reference to the JSON date value...>;
var dayValue = jsonDate.split("/")[2].replace(/0(.)/, "$1");
You've already got a string value, so might as well just manipulate it as a string.
jsonDate.split("/")[2] splits up the full date and then takes the third item from the resulting array (i.e., the day value)
.replace(/^0(.)$/, "$1") will trim off the "0", if it finds it in the first position of the "day" string
Then you just use dayValue wherever you need to use it. :)
UPDATE:
Based on the comments below, try using this as your code:
var listingEl = $('<div class="eventListings" title="' + item.event.title + '" />');
var dateEl = $('<div class="mdate">' + dayValue + '</div>');
var linkEl = $('<a href="' + item.event.localist_url + '" />');
var titleEl = $('<div class="mcTitle">' + item.event.title + '</div>');
linkEl.append(titleEl);
listingEl.append(dateEl);
listingEl.append(linkEl);
$('#localistTitle').append(listingEl);
UPDATE 2:
There was something not working in your code (I think the main issues was how you were using .appendTo()). I split it out into a multi-step process and used .append() instead. It worked correctly when I tested it locally.
I apologize for the question because I have already posted a similar question, but I would like to know how I can do the following conversion:
PT11H9M38.7876754S
I want to disable seconds and only show hour and minutes 11:09
When I have time displays minutes from 1 to 9, I want to add a 0 in front of number
Tnx in advice...
You could try this:
var str = 'PT11H9M38.7876754S'
match = str.match(/(\d*)H(\d*)M/),
formatted = match[1] + ':' + (!match[2][1] ? 0 + match[2] : match[2]);
console.log(formatted); // => 11:09
"PT11H9M38.78767545".replace(/PT(\d+)H(\d+)M.*/,function(m,a,b) {return a+":"+(b.length<2?"0":"")+b;});
One-liner :p
Since all the nice RegExp stuff is above here is a third solution a bit more expensive in terms of parsing but you may be looking for something different.
You can use the split function to parse the string and extract the portions that you need.
var pt="PT11H9M38.7876754S";
function showtime(s){
var time = s.split('.');
var hours = time[0].split('T')[1].split('H')[0];
var minutes = time[0].split('H')[1].split('M')[0];
return digitize(hours) + ":" + digitize(minutes)
}
function digitize(i){
return (i>9) ? i : "0" + i;
}
alert(showtime(pt)); // 11:09
If I have a date like 8/9/2010 in a textbox, how can I easiest set a variable to the value 201098?
Thanks in advance.
var date = "8/9/2010";
var result = date.split('/').reverse().join('');
EXAMPLE: http://jsfiddle.net/hX357/
To add leading zeros to the month and day (when needed) you could do this:
var date = "8/9/2010";
var result = date.split('/');
for( var i = 2; i--; )
result[i] = ("0" + result[i]).slice(-2);
result = result.reverse().join('');
EXAMPLE: http://jsfiddle.net/hX357/2/
I would recommend using Datejs to process your dates.
You can do something like
date.toString("yyyyMMdd");
to get the date in the format you want
Using regex:
"8/9/2010".replace(/([0-9]+)\/([0-9]+)\/([0-9]+)/,"$3$2$1")
Do a split on '/', take the last element and make it the first of a new string, the middle element becomes the middle element of the new string, and the first element becomes the last element of a new string.
It would be like this:
myString = document.getElementById('date_textbox').value;
var mySplitResult = myString.split("\");
var newString = mySplitResult[2] + mySplitResult[1] + mySplitResult[0];
This is basically the idea I think you are going for.
-Brian J. Stinar-
Dang, it looks like I was beaten to the punch...
Or you can use the built-in JavaScript Date class:
function processDate(dStr) {
var d = new Date(dStr);
return d.getFullYear() + (d.getMonth() + 1) + d.getDate();
}
processDate("8/9/2010");
Easiest to manage and debug, certainly.