Sorting months according to calendar year - c#

I currently have some code that can sort strings in alphabetic order. I would like for it to sort the months according to the calendar year. I have seen ways to do it on this website but cant apply them to my code specifically. What would I need to add to make it sort in order (January, February etc etc).
Code to read months to array:
var month1Values = File
.ReadAllLines(monthFilePath)
.Select(x => new { Name = monthFilePath, Sort = DateTime.ParseExact(x, "MMMM", CultureInfo.InvariantCulture) })
.ToArray();
Code to sort:
if (SortFile == 3)
{
comparison1 = string.Compare(fileData[index].MonthValues,
fileData[index + 1].MonthValues) > 0;
if (comparison1)
{
temp = fileData[index].MonthValues;
fileData[index].MonthValues = fileData[index + 1].MonthValues;
fileData[index + 1].MonthValues = temp;
swap = true;
}
}
Error appears where asterix is:
for (var index = 0; index < datasize; index++)
{
fileData[index] = new FileData
{
DayValues = day1Values[index],
MonthValues = *month1Values[index]*,
};
}
Error reads cannot convert type '< annonymous type: string Name, System.DateTime Sort >' to 'string'. How do I fix this problem?

You are creating anonymous data types in your Select instruction (first code box, line 3) instead of relying on DateTime type. The runtime don't know how to cast your anonymous type to String.
This should work as expected:
.Select(x => DateTime.ParseExact(x, "MMMM", CultureInfo.InvariantCulture))
Be aware that normal DateTime->String cast involves creating a full date from only month given; this involves assuming that day and year is current with hour, minute and second zeroed out.

Related

C# How to loop through an array and find array with most recent date?

New C# learner here. I've scanned through many questions that have already been posted here; I'm sorry if I missed a question like this that has already been asked.
Background
A program I use produces Excel files which have names that contain the date in which they are created. Thousands of Excel files are produced which need to be sorted. My mission here is to extract information from these file names so I am able to move the file to its appropriate location upon confirmation. I am working with a program that successfully finds all associated files with a particular string. I have stored the names of these files within an array.
Example File Name: IMPORTANT_NAME_LISTED (TEXT) [xx-xx-xx] [HH_MM].xlsx
What Is Known
The date is stored within "[ ]" in month/day/year format and it 100 % consistent (meaning that every file will produce the same format, size and location of the date).
I have been trying to develop a solution which targets "." before the file extension and extract the date, but I am struggling.
My Strategy
I have an initial decision, making sure the array that has all of the file names stored contains values.
//code that extracts file names exists above
//file names which interest me are stored within "fileNameArray"
//Determine if the array that collected file names contains values
if (fileNameArray.Length > 1)
{
for (int k = 0; k <= fileNameArray.Length; k++)
{
//Extract date from "[xx-xx-xx] [HH-MM]"
//Transform MM/DD/YY to YY/MM/DD and temporarily store
//Compare each date value that exist within the string
//Target the most recent file - find the array index
//(Ex: 20180831 - today's date)
}
}
My problems stem from properly parsing these individual array items while retaining the array index.
Do any of you recommend a method to use?
LINQ?
Array.FindAll functionality?
I greatly appreciate the help.
-Chris
Edit: Further Information about my situation...
I have a directory of Excel files, which can be in excess of ~1-3k files. I have a program which reads the file names of all of Excel files. A lot of the heavy filtering/sorting takes place before the code I have above which I want to implement.
I have been struggling with solving the issue with respect to handling files with the same name. For example:
I have 4 files that contain the same partial name "DILITHIUM_CRYSTYAL_FUEL_TIME"
My program must be able to filter/search file names through the core name "DILITHIUM_CRYSTYAL_FUEL_TIME". If I have more than one file with the same name, I need to be able to parse the file names in a way which isolates the time stamp within the file name and finds the most recent file.
My files will always show the time stamp, to the left of the file extension, in a 100% consistent manner.
I need to be able to extract this time stamp, and run comparisons against the other files, and isolate the file which is most up-to-date.
LINQ is a good choice for this, combined with Regex for parsing.
var dateRE = new Regex(#"\[(\d\d-\d\d-\d\d)\] \[(\d\d-\d\d)\](?=.xlsx)", RegexOptions.Compiled);
if (fileNameArray.Length > 0) {
var ans = fileNameArray.Select((n, i) => {
var dtMatch = dateRE.Match(n);
return new { Filename = n, Index = i, Filedate = DateTime.ParseExact(dtMatch.Groups[1].Value+" "+dtMatch.Groups[2].Value, "MM-dd-yy HH-mm", CultureInfo.InvariantCulture) };
})
.OrderByDescending(nid => nid.Filedate)
.First();
}
If you want to process the filenames differently, you can replace First() with some other LINQ operation.
I would also go for regex, string parsing and linq:
Working example here: https://dotnetfiddle.net/veUq2N
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
public class Program
{
private static Random random = new Random();
private static Regex fileNameFragmentPattern = new Regex(#"\[(.*?)\]\.xlsx");
private const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
public static void Main()
{
var fileNames = new List<string>();
// Generate random file names
for (var i = 0; i < 10000; i++) {
fileNames.Add(RandomString(random.Next(8,10)) + "_" + RandomString(random.Next(4,5)) + "_" + "(TEXT) [" + RandomDate().ToString("MM-dd-yyyy") + "].xlsx");
}
// sort files by parsed dates
var dateSortedFileNames = fileNames.OrderByDescending( f => ExtractDate(f));
foreach (var fileName in dateSortedFileNames) {
// you can do anything with sorted files here (or anywhere else below :)
Console.WriteLine(fileName);
}
}
public static DateTime ExtractDate(string fileName) {
var fragment = fileNameFragmentPattern.Match(fileName).Value;
var month = int.Parse(fragment.Substring(1,2));
var day = int.Parse(fragment.Substring(4,2));
var year = int.Parse(fragment.Substring(7,4));
return new DateTime(year, month, day);
}
public static string RandomString(int length)
{
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
public static DateTime RandomDate(int min = -9999, int max = 9999)
{
return DateTime.Now.AddDays(random.Next(min,max));
}
}
Here's a non-regex solution.
var files = new List<string>
{
"IMPORTANT_NAME_LISTED (TEXT) [05-26-92].xlsx",
"IMPORTANT_NAME_LISTED (TEXT) [11-02-89].xlsx",
"IMPORTANT_NAME_LISTED (TEXT) [02-21-96].xlsx"
};
foreach (var fileName in files)
{
var nameOnly = Path.GetFileNameWithoutExtension(fileName);
var dateStr = nameOnly.Substring(nameOnly.Length - 9, 8);
if (DateTime.TryParseExact(dateStr, "MM-dd-yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
Console.WriteLine(date.ToShortDateString());
}
Since you mention that the 'date' part of the file name is 100% consistent, and we know that the length of your 'date' will always be 8. So using that knowledge,
nameOnly.Substring(nameOnly.Length - 9, 8);
will extract the string starting right after the first [, and will extract 8 characters ending before ].
And if you're 100% positive that the file extension will always be .xlsx, then you can shorten the code even more.
foreach (var fileName in files)
{
var dateStr = fileName.Substring(fileName.Length - 14, 8);
if (DateTime.TryParseExact(dateStr, "MM-dd-yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out DateTime date))
Console.WriteLine(date.ToShortDateString());
}
I wanted to post here again, with what I used to solve my programming problem. It has been a busy past week or so, I apologize for the delay.
Here is a snippet from my code that solved my problem beautifully:
string scanToolDateFinalStgT1 = "";
DateTime scanToolDateFinalT1 = new DateTime(2000, 1, 1, 1, 1, 00);
for (int k = 0; k < scanToolT1Pass.Count(); k++)
{
string scanToolPassNameOnly = Path.GetFileNameWithoutExtension(scanToolT1Pass[k].ToString());
string scanToolDateStr = scanToolPassNameOnly.Substring(scanToolPassNameOnly.IndexOf("[") + 1, 8);
string scanToolTimeStr = scanToolPassNameOnly.Substring(scanToolPassNameOnly.LastIndexOf("[") + 1, 5);
DateTime currentScanToolDate = DateTime.ParseExact(scanToolDateStr + " " + scanToolTimeStr, "MM-dd-yy HH_mm", null);
if (currentScanToolDate > scanToolDateFinalT1)
{
scanToolDateFinalT1 = currentScanToolDate;
scanToolDateFinalStgT1 = scanToolT1Pass[k].ToString();
}
}
Information:
This snippet is aimed at targeting '[xx-xx-xx] [xx-xx].', which is a partial unique identifier for a file name.
The program is passing in 'scanToolT1Pass', which is an array of file names. My task is to take this array and parse the file names, finding the most recent one.
'DateTime scanToolDateFinalT1' has a generic date of 1/01/200, 1:01:00, which is strictly used as a base comparison point. I am certain my data will never require dates which happen before the year 2000. I tried to have a reference date reading all zeros to compare to, but VisualStudio did not approve of that.
Explanation:
Are there more advanced and/or proper methods to parse this data? I'm sure there is. But, for a beginner programmer, this method makes a lot or sense to me and I aim to perfect it in the future. It was most important to me to have a program that functions first, than to invest a lot of study into polishing it.
I was able to implement similar for loops throughout my program, filtering through large amounts of data at a very rapid pace.
Thanks again to the community and to #Sach & #It Man, whose responses I was able to craft into my solution.
Chris
Simpler alternative :
var regex = new Regex(".*\[(.*)-(.*)] \[(.*)].*");
string latest = fileNameArray.OrderBy(s => regex.Replace(s, "$2$1$3")).Last();
Demo and explanation of the pattern can be seen on https://regex101.com/r/Ldh0sa
public struct DatedExcelOutput
{
public string FullName { get; }
public string Name { get; }
public DateTime CreationDate { get; }
public DatedExcelOutput(string fileName)
{
FullName = fileName;
Name = getName();
CreationDate = parseDate();
}
}
It could be called like this:
IEnumerable<string> fileNames = GetFiles();
var datedFiles = fileNames.Select(f => new DatedExcelOutput(f))
.OrderBy(d => d.CreationDate);
You'll likely end up needing to sort these ascending/descending in a UI right? So I don't think it makes sense to throw the date information away.
Edit: Removed unnecessary IO calls as NetMage pointed out.

Read DateTime value in correct format with JQuery (passed from controller to ajax) [duplicate]

I'm taking my first crack at Ajax with jQuery. I'm getting my data onto my page, but I'm having some trouble with the JSON data that is returned for Date data types. Basically, I'm getting a string back that looks like this:
/Date(1224043200000)/
From someone totally new to JSON - How do I format this to a short date format? Should this be handled somewhere in the jQuery code? I've tried the jQuery.UI.datepicker plugin using $.datepicker.formatDate() without any success.
FYI: Here's the solution I came up with using a combination of the answers here:
function getMismatch(id) {
$.getJSON("Main.aspx?Callback=GetMismatch",
{ MismatchId: id },
function (result) {
$("#AuthMerchId").text(result.AuthorizationMerchantId);
$("#SttlMerchId").text(result.SettlementMerchantId);
$("#CreateDate").text(formatJSONDate(Date(result.AppendDts)));
$("#ExpireDate").text(formatJSONDate(Date(result.ExpiresDts)));
$("#LastUpdate").text(formatJSONDate(Date(result.LastUpdateDts)));
$("#LastUpdatedBy").text(result.LastUpdateNt);
$("#ProcessIn").text(result.ProcessIn);
}
);
return false;
}
function formatJSONDate(jsonDate) {
var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
return newDate;
}
This solution got my object from the callback method and displayed the dates on the page properly using the date format library.
eval() is not necessary. This will work fine:
var date = new Date(parseInt(jsonDate.substr(6)));
The substr() function takes out the /Date( part, and the parseInt() function gets the integer and ignores the )/ at the end. The resulting number is passed into the Date constructor.
I have intentionally left out the radix (the 2nd argument to parseInt); see my comment below.
Also, I completely agree with Rory's comment: ISO-8601 dates are preferred over this old format - so this format generally shouldn't be used for new development.
For ISO-8601 formatted JSON dates, just pass the string into the Date constructor:
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
You can use this to get a date from JSON:
var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
And then you can use a JavaScript Date Format script (1.2 KB when minified and gzipped) to display it as you want.
For those using Newtonsoft Json.NET, read up on how to do it via Native JSON in IE8, Firefox 3.5 plus Json.NET.
Also the documentation on changing the format of dates written by Json.NET is useful:
Serializing Dates with Json.NET
For those that are too lazy, here are the quick steps. As JSON has a loose DateTime implementation, you need to use the IsoDateTimeConverter(). Note that since Json.NET 4.5 the default date format is ISO so the code below isn't needed.
string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());
The JSON will come through as
"fieldName": "2009-04-12T20:44:55"
Finally, some JavaScript to convert the ISO date to a JavaScript date:
function isoDateReviver(value) {
if (typeof value === 'string') {
var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(?:([\+-])(\d{2})\:(\d{2}))?Z?$/.exec(value);
if (a) {
var utcMilliseconds = Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]);
return new Date(utcMilliseconds);
}
}
return value;
}
I used it like this
$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);
The original example:
/Date(1224043200000)/
does not reflect the formatting used by WCF when sending dates via WCF REST using the built-in JSON serialization. (at least on .NET 3.5, SP1)
I found the answer here helpful, but a slight edit to the regex is required, as it appears that the timezone GMT offset is being appended onto the number returned (since 1970) in WCF JSON.
In a WCF service I have:
[OperationContract]
[WebInvoke(
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest
)]
ApptVisitLinkInfo GetCurrentLinkInfo( int appointmentsId );
ApptVisitLinkInfo is defined simply:
public class ApptVisitLinkInfo {
string Field1 { get; set; }
DateTime Field2 { get; set; }
...
}
When "Field2" is returned as Json from the service the value is:
/Date(1224043200000-0600)/
Notice the timezone offset included as part of the value.
The modified regex:
/\/Date\((.*?)\)\//gi
It's slightly more eager and grabs everything between the parens, not just the first number. The resulting time sinze 1970, plus timezone offset can all be fed into the eval to get a date object.
The resulting line of JavaScript for the replace is:
replace(/\/Date\((.*?)\)\//gi, "new Date($1)");
Don't repeat yourself - automate date conversion using $.parseJSON()
Answers to your post provide manual date conversion to JavaScript dates. I've extended jQuery's $.parseJSON() just a little bit, so it's able to automatically parse dates when you instruct it to. It processes ASP.NET formatted dates (/Date(12348721342)/) as well as ISO formatted dates (2010-01-01T12.34.56.789Z) that are supported by native JSON functions in browsers (and libraries like json2.js).
Anyway. If you don't want to repeat your date conversion code over and over again I suggest you read this blog post and get the code that will make your life a little easier.
Click here to check the Demo
JavaScript/jQuery
var = MyDate_String_Value = "/Date(1224043200000)/"
var value = new Date
(
parseInt(MyDate_String_Value.replace(/(^.*\()|([+-].*$)/g, ''))
);
var dat = value.getMonth() +
1 +
"/" +
value.getDate() +
"/" +
value.getFullYear();
Result - "10/15/2008"
If you say in JavaScript,
var thedate = new Date(1224043200000);
alert(thedate);
you will see that it's the correct date, and you can use that anywhere in JavaScript code with any framework.
Updated
We have an internal UI library that has to cope with both Microsoft's ASP.NET built-in JSON format, like /Date(msecs)/, asked about here originally, and most JSON's date format including JSON.NET's, like 2014-06-22T00:00:00.0. In addition we need to cope with oldIE's inability to cope with anything but 3 decimal places.
We first detect what kind of date we're consuming, parse it into a normal JavaScript Date object, then format that out.
1) Detect Microsoft Date format
// Handling of Microsoft AJAX Dates, formatted like '/Date(01238329348239)/'
function looksLikeMSDate(s) {
return /^\/Date\(/.test(s);
}
2) Detect ISO date format
var isoDateRegex = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d\d?\d?)?([\+-]\d\d:\d\d|Z)?$/;
function looksLikeIsoDate(s) {
return isoDateRegex.test(s);
}
3) Parse MS date format:
function parseMSDate(s) {
// Jump forward past the /Date(, parseInt handles the rest
return new Date(parseInt(s.substr(6)));
}
4) Parse ISO date format.
We do at least have a way to be sure that we're dealing with standard ISO dates or ISO dates modified to always have three millisecond places (see above), so the code is different depending on the environment.
4a) Parse standard ISO Date format, cope with oldIE's issues:
function parseIsoDate(s) {
var m = isoDateRegex.exec(s);
// Is this UTC, offset, or undefined? Treat undefined as UTC.
if (m.length == 7 || // Just the y-m-dTh:m:s, no ms, no tz offset - assume UTC
(m.length > 7 && (
!m[7] || // Array came back length 9 with undefined for 7 and 8
m[7].charAt(0) != '.' || // ms portion, no tz offset, or no ms portion, Z
!m[8] || // ms portion, no tz offset
m[8] == 'Z'))) { // ms portion and Z
// JavaScript's weirdo date handling expects just the months to be 0-based, as in 0-11, not 1-12 - the rest are as you expect in dates.
var d = new Date(Date.UTC(m[1], m[2]-1, m[3], m[4], m[5], m[6]));
} else {
// local
var d = new Date(m[1], m[2]-1, m[3], m[4], m[5], m[6]);
}
return d;
}
4b) Parse ISO format with a fixed three millisecond decimal places - much easier:
function parseIsoDate(s) {
return new Date(s);
}
5) Format it:
function hasTime(d) {
return !!(d.getUTCHours() || d.getUTCMinutes() || d.getUTCSeconds());
}
function zeroFill(n) {
if ((n + '').length == 1)
return '0' + n;
return n;
}
function formatDate(d) {
if (hasTime(d)) {
var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
s += ' ' + d.getHours() + ':' + zeroFill(d.getMinutes()) + ':' + zeroFill(d.getSeconds());
} else {
var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
}
return s;
}
6) Tie it all together:
function parseDate(s) {
var d;
if (looksLikeMSDate(s))
d = parseMSDate(s);
else if (looksLikeIsoDate(s))
d = parseIsoDate(s);
else
return null;
return formatDate(d);
}
The below old answer is useful for tying this date formatting into jQuery's own JSON parsing so you get Date objects instead of strings, or if you're still stuck in jQuery <1.5 somehow.
Old Answer
If you're using jQuery 1.4's Ajax function with ASP.NET MVC, you can turn all DateTime properties into Date objects with:
// Once
jQuery.parseJSON = function(d) {return eval('(' + d + ')');};
$.ajax({
...
dataFilter: function(d) {
return d.replace(/"\\\/(Date\(-?\d+\))\\\/"/g, 'new $1');
},
...
});
In jQuery 1.5 you can avoid overriding the parseJSON method globally by using the converters option in the Ajax call.
http://api.jquery.com/jQuery.ajax/
Unfortunately you have to switch to the older eval route in order to get Dates to parse globally in-place - otherwise you need to convert them on a more case-by-case basis post-parse.
There is no built in date type in JSON. This looks like the number of seconds / milliseconds from some epoch. If you know the epoch you can create the date by adding on the right amount of time.
I also had to search for a solution to this problem and eventually I came across moment.js which is a nice library that can parse this date format and many more.
var d = moment(yourdatestring)
It saved some headache for me so I thought I'd share it with you. :)
You can find some more info about it here: http://momentjs.com/
I ended up adding the "characters into Panos's regular expression to get rid of the ones generated by the Microsoft serializer for when writing objects into an inline script:
So if you have a property in your C# code-behind that's something like
protected string JsonObject { get { return jsSerialiser.Serialize(_myObject); }}
And in your aspx you have
<script type="text/javascript">
var myObject = '<%= JsonObject %>';
</script>
You'd get something like
var myObject = '{"StartDate":"\/Date(1255131630400)\/"}';
Notice the double quotes.
To get this into a form that eval will correctly deserialize, I used:
myObject = myObject.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
I use Prototype and to use it I added
String.prototype.evalJSONWithDates = function() {
var jsonWithDates = this.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
return jsonWithDates.evalJSON(true);
}
In jQuery 1.5, as long as you have json2.js to cover for older browsers, you can deserialize all dates coming from Ajax as follows:
(function () {
var DATE_START = "/Date(";
var DATE_START_LENGTH = DATE_START.length;
function isDateString(x) {
return typeof x === "string" && x.startsWith(DATE_START);
}
function deserializeDateString(dateString) {
var dateOffsetByLocalTime = new Date(parseInt(dateString.substr(DATE_START_LENGTH)));
var utcDate = new Date(dateOffsetByLocalTime.getTime() - dateOffsetByLocalTime.getTimezoneOffset() * 60 * 1000);
return utcDate;
}
function convertJSONDates(key, value) {
if (isDateString(value)) {
return deserializeDateString(value);
}
return value;
}
window.jQuery.ajaxSetup({
converters: {
"text json": function(data) {
return window.JSON.parse(data, convertJSONDates);
}
}
});
}());
I included logic that assumes you send all dates from the server as UTC (which you should); the consumer then gets a JavaScript Date object that has the proper ticks value to reflect this. That is, calling getUTCHours(), etc. on the date will return the same value as it did on the server, and calling getHours() will return the value in the user's local timezone as determined by their browser.
This does not take into account WCF format with timezone offsets, though that would be relatively easy to add.
Using the jQuery UI datepicker - really only makes sense if you're already including jQuery UI:
$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6))));
output:
October 15, 2008
Don't over-think this. Like we've done for decades, pass a numeric offset from the de-facto standard epoch of 1 Jan 1970 midnight GMT/UTC/&c in number of seconds (or milliseconds) since this epoch. JavaScript likes it, Java likes it, C likes it, and the Internet likes it.
Everyone of these answers has one thing in common: they all store dates as a single value (usually a string).
Another option is to take advantage of the inherent structure of JSON, and represent a date as list of numbers:
{ "name":"Nick",
"birthdate":[1968,6,9] }
Of course, you would have to make sure both ends of the conversation agree on the format (year, month, day), and which fields are meant to be dates,... but it has the advantage of completely avoiding the issue of date-to-string conversion. It's all numbers -- no strings at all. Also, using the order: year, month, day also allows proper sorting by date.
Just thinking outside the box here -- a JSON date doesn't have to be stored as a string.
Another bonus to doing it this way is that you can easily (and efficiently) select all records for a given year or month by leveraging the way CouchDB handles queries on array values.
Posting in awesome thread:
var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));
Just to add another approach here, the "ticks approach" that WCF takes is prone to problems with timezones if you're not extremely careful such as described here and in other places. So I'm now using the ISO 8601 format that both .NET & JavaScript duly support that includes timezone offsets. Below are the details:
In WCF/.NET:
Where CreationDate is a System.DateTime; ToString("o") is using .NET's Round-trip format specifier that generates an ISO 8601-compliant date string
new MyInfo {
CreationDate = r.CreationDate.ToString("o"),
};
In JavaScript
Just after retrieving the JSON I go fixup the dates to be JavaSript Date objects using the Date constructor which accepts an ISO 8601 date string...
$.getJSON(
"MyRestService.svc/myinfo",
function (data) {
$.each(data.myinfos, function (r) {
this.CreatedOn = new Date(this.CreationDate);
});
// Now each myinfo object in the myinfos collection has a CreatedOn field that is a real JavaScript date (with timezone intact).
alert(data.myinfos[0].CreationDate.toLocaleString());
}
)
Once you have a JavaScript date you can use all the convenient and reliable Date methods like toDateString, toLocaleString, etc.
var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
Is there another option without using the jQuery library?
This may can also help you.
function ToJavaScriptDate(value) { //To Parse Date from the Returned Parsed Date
var pattern = /Date\(([^)]+)\)/;
var results = pattern.exec(value);
var dt = new Date(parseFloat(results[1]));
return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
}
I get the date like this:
"/Date(1276290000000+0300)/"
In some examples the date is in slightly different formats:
"/Date(12762900000000300)/"
"Date(1276290000000-0300)"
etc.
So I came up with the following RegExp:
/\/+Date\(([\d+]+)\)\/+/
and the final code is:
var myDate = new Date(parseInt(jsonWcfDate.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1')));
Hope it helps.
Update:
I found this link from Microsoft:
How do I Serialize Dates with JSON?
This seems like the one we are all looking for.
Below is a pretty simple solution for parsing JSON dates. Use the below functions as per your requirement. You just need to pass the JSON format Date fetched as a parameter to the functions below:
function JSONDate(dateStr) {
var m, day;
jsonDate = dateStr;
var d = new Date(parseInt(jsonDate.substr(6)));
m = d.getMonth() + 1;
if (m < 10)
m = '0' + m
if (d.getDate() < 10)
day = '0' + d.getDate()
else
day = d.getDate();
return (m + '/' + day + '/' + d.getFullYear())
}
function JSONDateWithTime(dateStr) {
jsonDate = dateStr;
var d = new Date(parseInt(jsonDate.substr(6)));
var m, day;
m = d.getMonth() + 1;
if (m < 10)
m = '0' + m
if (d.getDate() < 10)
day = '0' + d.getDate()
else
day = d.getDate();
var formattedDate = m + "/" + day + "/" + d.getFullYear();
var hours = (d.getHours() < 10) ? "0" + d.getHours() : d.getHours();
var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes();
var formattedTime = hours + ":" + minutes + ":" + d.getSeconds();
formattedDate = formattedDate + " " + formattedTime;
return formattedDate;
}
You also can use the JavaScript library moment.js, which comes in handy when you plan do deal with different localized formats and perform other operations with dates values:
function getMismatch(id) {
$.getJSON("Main.aspx?Callback=GetMismatch",
{ MismatchId: id },
function (result) {
$("#AuthMerchId").text(result.AuthorizationMerchantId);
$("#SttlMerchId").text(result.SettlementMerchantId);
$("#CreateDate").text(moment(result.AppendDts).format("L"));
$("#ExpireDate").text(moment(result.ExpiresDts).format("L"));
$("#LastUpdate").text(moment(result.LastUpdateDts).format("L"));
$("#LastUpdatedBy").text(result.LastUpdateNt);
$("#ProcessIn").text(result.ProcessIn);
}
);
return false;
}
Setting up localization is as easy as adding configuration files (you get them at momentjs.com) to your project and configuring the language:
moment.lang('de');
Check up the date ISO standard; kind of like this:
yyyy.MM.ddThh:mm
It becomes 2008.11.20T22:18.
This is frustrating. My solution was to parse out the "/ and /" from the value generated by ASP.NET's JavaScriptSerializer so that, though JSON may not have a date literal, it still gets interpreted by the browser as a date, which is what all I really want:{"myDate":Date(123456789)}
Custom JavaScriptConverter for DateTime?
I must emphasize the accuracy of Roy Tinker's comment. This is not legal JSON. It's a dirty, dirty hack on the server to remove the issue before it becomes a problem for JavaScript. It will choke a JSON parser. I used it for getting off the ground, but I do not use this any more. However, I still feel the best answer lies with changing how the server formats the date, for example, ISO as mentioned elsewhere.
A late post, but for those who searched this post.
Imagine this:
[Authorize(Roles = "Administrator")]
[Authorize(Roles = "Director")]
[Authorize(Roles = "Human Resources")]
[HttpGet]
public ActionResult GetUserData(string UserIdGuidKey)
{
if (UserIdGuidKey!= null)
{
var guidUserId = new Guid(UserIdGuidKey);
var memuser = Membership.GetUser(guidUserId);
var profileuser = Profile.GetUserProfile(memuser.UserName);
var list = new {
UserName = memuser.UserName,
Email = memuser.Email ,
IsApproved = memuser.IsApproved.ToString() ,
IsLockedOut = memuser.IsLockedOut.ToString() ,
LastLockoutDate = memuser.LastLockoutDate.ToString() ,
CreationDate = memuser.CreationDate.ToString() ,
LastLoginDate = memuser.LastLoginDate.ToString() ,
LastActivityDate = memuser.LastActivityDate.ToString() ,
LastPasswordChangedDate = memuser.LastPasswordChangedDate.ToString() ,
IsOnline = memuser.IsOnline.ToString() ,
FirstName = profileuser.FirstName ,
LastName = profileuser.LastName ,
NickName = profileuser.NickName ,
BirthDate = profileuser.BirthDate.ToString() ,
};
return Json(list, JsonRequestBehavior.AllowGet);
}
return Redirect("Index");
}
As you can see, I'm utilizing C# 3.0's feature for creating the "Auto" Generics. It's a bit lazy, but I like it and it works.
Just a note: Profile is a custom class I've created for my web application project.
FYI, for anyone using Python on the server side: datetime.datetime().ctime() returns a string that is natively parsable by "new Date()". That is, if you create a new datetime.datetime instance (such as with datetime.datetime.now), the string can be included in the JSON string, and then that string can be passed as the first argument to the Date constructor. I haven't yet found any exceptions, but I haven't tested it too rigorously, either.
Mootools solution:
new Date(Date(result.AppendDts)).format('%x')
Requires mootools-more. Tested using mootools-1.2.3.1-more on Firefox 3.6.3 and IE 7.0.5730.13
var obj = eval('(' + "{Date: \/Date(1278903921551)\/}".replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')');
var dateValue = obj["Date"];
Add the jQuery UI plugin in your page:
function DateFormate(dateConvert) {
return $.datepicker.formatDate("dd/MM/yyyy", eval('new ' + dateConvert.slice(1, -1)));
};
What if .NET returns...
return DateTime.Now.ToString("u"); //"2013-09-17 15:18:53Z"
And then in JavaScript...
var x = new Date("2013-09-17 15:18:53Z");

C# Index Out Of Range Exception when creating date

I have written a piece of code where it connects to SQL Server to retrieve some data from the database. One type of these data that I need is a stored date for something. This works fine, it connects and retrieves all the data I want from it, but when I try to create a DateTime using the retrieved date I've got from SQL it gives me a Index Out of Range Exception.
Here is the code for it:
//sDate contains 14/11/2014 so dateArr[0] contains 14, dateArr[1] contains 11 and dateArr[2] contains 2014
for(int i = 0; i < dataSet.Tables[0].Rows.Count; i++)
{
if(dataSet.Tables[0].Rows[i][9] != DBNull.Value)
{
String[] sDateAndTime = dataSet.Tables[0].Rows[i][9].ToString().Split(' ');
String sDate = sDateAndTime[0];
String[] dateArr = sDate.Split('/');
DateTime date = new DateTime(Convert.ToInt32(dateArr[3]), Convert.ToInt32(dateArr[2]), Convert.ToInt32(dateArr[1]));
Console.WriteLine(dateArr[0] + " " + dateArr[1] + " " + dateArr[2]);
}
}
The strange thing is that the error only comes up on line DateTime date = new DateTime(Convert.ToInt32(dateArr[3]), Convert.ToInt32(dateArr[2]), Convert.ToInt32(dateArr[1]));
If I comment that line out, it works totally fine. Can someone please let me know what is it that I'm doing wrong? I've tried all kinds of methods including using DateTime.ParseExact but it still doesn't work (give a different error).
Arrays indexes are 0 based. Try this:
DateTime date = new DateTime(Convert.ToInt32(dateArr[2]), Convert.ToInt32(dateArr[1]), Convert.ToInt32(dateArr[0]));

Split string issues with null position

I have a string of the days of the week. I parse it in C# and store each day in a separate variable. For example:
string weekdayName = "Mon,Tue,Wed,Thu,Fri,Sat,Sun";
And the I split them using ',' as a delimiter:
var weekDayName = weekDay.Split(',');
var firstDay = weekDayName[0];
var secondDay = weekDayName[1];
var thirdDay = weekDayName[2];
var fourthDay = weekDayName[3];
var fifthDay = weekDayName[4];
var sixDay = weekDayName[5];
var seventhDay = weekDayName[6];
Everything works. However, the string dynamically changes. A user assigns the days of the week. For example a string weekDayName could only contain "Mon,Tue". But the problem i'm running into is if not all the position contains value it will fail.
Index was outside the bounds of the array.
I have tried:
if (weekDayName[5].Length >0)
{
var sixDay = weekDayName[5];
}
But it still fails...
How can I check and grab the value of the existing data, if some of the position are missing I just ignore them?
What I'm trying to achieve is:
DateTime currentDay = new DateTime();
currentDay = DateTime.Now;
if (currentDay.ToString("ddd") == firstDay || currentDay.ToString("ddd") == seconday)
{
// I will check the currentDay against every day of the week
//do something
}
Your index out of range is not coming from where you think. I am of course assuming this since you tried to check length on an element that was never set if the user enters Mon,Tue.
var enteredDays = weekDay.Split(',');
for(var i = 0; i < enteredDays.Length; i++)
{
var day = enteredDays[i];
if(i == 0)
first = day;
else if(i == 1)
second = day;
... etc....
}
Now you can check String.IsNullOrEmpty(..yourDay..) when you need to use the values you pulled from the array. You can't use .Length on them because they are null and will blow up unless you default them all to string.Empty.
There must be some smarter way of doing this, but since i do not know where the string originates from, it is hard for me to make a better solution.
However, given the current requirements, you could do something like:
string weekdayName = "Mon,Tue,Wed,Thu,Fri,Sat,Sun";
List<String> weekDaysList = weekdayName.Split(',').ToList();
foreach (var weekDay in weekDaysList.Take(2))
{
if (weekDay == DateTime.Now.ToString("ddd"))
{
// do something
break;
}
}
If you're willing to try Linq (which is a language feature of C# 3.5 and higher, just include the System.Linq namespace) you could do it like this:
string[] names = weekdayName
.Split(',')
.Select(s => s.Trim())
.Where(s => s.Length > 0)
.ToArray();
The names array now contains all non-empty day names, without any leading or trailing spaces.
Wow that's a lot of code for a simple check, As mentioned by other members you can use LINQ to merge all validations in single query something like :
string weekdayName = "Mon,Tue,Wed,Thu,Fri,Sat,Sun";
var wc = weekdayName.Split(',');
if (wc.Any(str => str.Contains(DateTime.Today.DayOfWeek.ToString().Substring(0,3))))
{
}
Try this and let me know if you have any concerns.

Convert .NET UTC Time in JavaScript [duplicate]

I'm taking my first crack at Ajax with jQuery. I'm getting my data onto my page, but I'm having some trouble with the JSON data that is returned for Date data types. Basically, I'm getting a string back that looks like this:
/Date(1224043200000)/
From someone totally new to JSON - How do I format this to a short date format? Should this be handled somewhere in the jQuery code? I've tried the jQuery.UI.datepicker plugin using $.datepicker.formatDate() without any success.
FYI: Here's the solution I came up with using a combination of the answers here:
function getMismatch(id) {
$.getJSON("Main.aspx?Callback=GetMismatch",
{ MismatchId: id },
function (result) {
$("#AuthMerchId").text(result.AuthorizationMerchantId);
$("#SttlMerchId").text(result.SettlementMerchantId);
$("#CreateDate").text(formatJSONDate(Date(result.AppendDts)));
$("#ExpireDate").text(formatJSONDate(Date(result.ExpiresDts)));
$("#LastUpdate").text(formatJSONDate(Date(result.LastUpdateDts)));
$("#LastUpdatedBy").text(result.LastUpdateNt);
$("#ProcessIn").text(result.ProcessIn);
}
);
return false;
}
function formatJSONDate(jsonDate) {
var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
return newDate;
}
This solution got my object from the callback method and displayed the dates on the page properly using the date format library.
eval() is not necessary. This will work fine:
var date = new Date(parseInt(jsonDate.substr(6)));
The substr() function takes out the /Date( part, and the parseInt() function gets the integer and ignores the )/ at the end. The resulting number is passed into the Date constructor.
I have intentionally left out the radix (the 2nd argument to parseInt); see my comment below.
Also, I completely agree with Rory's comment: ISO-8601 dates are preferred over this old format - so this format generally shouldn't be used for new development.
For ISO-8601 formatted JSON dates, just pass the string into the Date constructor:
var date = new Date(jsonDate); //no ugly parsing needed; full timezone support
You can use this to get a date from JSON:
var date = eval(jsonDate.replace(/\/Date\((\d+)\)\//gi, "new Date($1)"));
And then you can use a JavaScript Date Format script (1.2 KB when minified and gzipped) to display it as you want.
For those using Newtonsoft Json.NET, read up on how to do it via Native JSON in IE8, Firefox 3.5 plus Json.NET.
Also the documentation on changing the format of dates written by Json.NET is useful:
Serializing Dates with Json.NET
For those that are too lazy, here are the quick steps. As JSON has a loose DateTime implementation, you need to use the IsoDateTimeConverter(). Note that since Json.NET 4.5 the default date format is ISO so the code below isn't needed.
string jsonText = JsonConvert.SerializeObject(p, new IsoDateTimeConverter());
The JSON will come through as
"fieldName": "2009-04-12T20:44:55"
Finally, some JavaScript to convert the ISO date to a JavaScript date:
function isoDateReviver(value) {
if (typeof value === 'string') {
var a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)(?:([\+-])(\d{2})\:(\d{2}))?Z?$/.exec(value);
if (a) {
var utcMilliseconds = Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6]);
return new Date(utcMilliseconds);
}
}
return value;
}
I used it like this
$("<span />").text(isoDateReviver(item.fieldName).toLocaleString()).appendTo("#" + divName);
The original example:
/Date(1224043200000)/
does not reflect the formatting used by WCF when sending dates via WCF REST using the built-in JSON serialization. (at least on .NET 3.5, SP1)
I found the answer here helpful, but a slight edit to the regex is required, as it appears that the timezone GMT offset is being appended onto the number returned (since 1970) in WCF JSON.
In a WCF service I have:
[OperationContract]
[WebInvoke(
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest
)]
ApptVisitLinkInfo GetCurrentLinkInfo( int appointmentsId );
ApptVisitLinkInfo is defined simply:
public class ApptVisitLinkInfo {
string Field1 { get; set; }
DateTime Field2 { get; set; }
...
}
When "Field2" is returned as Json from the service the value is:
/Date(1224043200000-0600)/
Notice the timezone offset included as part of the value.
The modified regex:
/\/Date\((.*?)\)\//gi
It's slightly more eager and grabs everything between the parens, not just the first number. The resulting time sinze 1970, plus timezone offset can all be fed into the eval to get a date object.
The resulting line of JavaScript for the replace is:
replace(/\/Date\((.*?)\)\//gi, "new Date($1)");
Don't repeat yourself - automate date conversion using $.parseJSON()
Answers to your post provide manual date conversion to JavaScript dates. I've extended jQuery's $.parseJSON() just a little bit, so it's able to automatically parse dates when you instruct it to. It processes ASP.NET formatted dates (/Date(12348721342)/) as well as ISO formatted dates (2010-01-01T12.34.56.789Z) that are supported by native JSON functions in browsers (and libraries like json2.js).
Anyway. If you don't want to repeat your date conversion code over and over again I suggest you read this blog post and get the code that will make your life a little easier.
Click here to check the Demo
JavaScript/jQuery
var = MyDate_String_Value = "/Date(1224043200000)/"
var value = new Date
(
parseInt(MyDate_String_Value.replace(/(^.*\()|([+-].*$)/g, ''))
);
var dat = value.getMonth() +
1 +
"/" +
value.getDate() +
"/" +
value.getFullYear();
Result - "10/15/2008"
If you say in JavaScript,
var thedate = new Date(1224043200000);
alert(thedate);
you will see that it's the correct date, and you can use that anywhere in JavaScript code with any framework.
Updated
We have an internal UI library that has to cope with both Microsoft's ASP.NET built-in JSON format, like /Date(msecs)/, asked about here originally, and most JSON's date format including JSON.NET's, like 2014-06-22T00:00:00.0. In addition we need to cope with oldIE's inability to cope with anything but 3 decimal places.
We first detect what kind of date we're consuming, parse it into a normal JavaScript Date object, then format that out.
1) Detect Microsoft Date format
// Handling of Microsoft AJAX Dates, formatted like '/Date(01238329348239)/'
function looksLikeMSDate(s) {
return /^\/Date\(/.test(s);
}
2) Detect ISO date format
var isoDateRegex = /^(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)(\.\d\d?\d?)?([\+-]\d\d:\d\d|Z)?$/;
function looksLikeIsoDate(s) {
return isoDateRegex.test(s);
}
3) Parse MS date format:
function parseMSDate(s) {
// Jump forward past the /Date(, parseInt handles the rest
return new Date(parseInt(s.substr(6)));
}
4) Parse ISO date format.
We do at least have a way to be sure that we're dealing with standard ISO dates or ISO dates modified to always have three millisecond places (see above), so the code is different depending on the environment.
4a) Parse standard ISO Date format, cope with oldIE's issues:
function parseIsoDate(s) {
var m = isoDateRegex.exec(s);
// Is this UTC, offset, or undefined? Treat undefined as UTC.
if (m.length == 7 || // Just the y-m-dTh:m:s, no ms, no tz offset - assume UTC
(m.length > 7 && (
!m[7] || // Array came back length 9 with undefined for 7 and 8
m[7].charAt(0) != '.' || // ms portion, no tz offset, or no ms portion, Z
!m[8] || // ms portion, no tz offset
m[8] == 'Z'))) { // ms portion and Z
// JavaScript's weirdo date handling expects just the months to be 0-based, as in 0-11, not 1-12 - the rest are as you expect in dates.
var d = new Date(Date.UTC(m[1], m[2]-1, m[3], m[4], m[5], m[6]));
} else {
// local
var d = new Date(m[1], m[2]-1, m[3], m[4], m[5], m[6]);
}
return d;
}
4b) Parse ISO format with a fixed three millisecond decimal places - much easier:
function parseIsoDate(s) {
return new Date(s);
}
5) Format it:
function hasTime(d) {
return !!(d.getUTCHours() || d.getUTCMinutes() || d.getUTCSeconds());
}
function zeroFill(n) {
if ((n + '').length == 1)
return '0' + n;
return n;
}
function formatDate(d) {
if (hasTime(d)) {
var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
s += ' ' + d.getHours() + ':' + zeroFill(d.getMinutes()) + ':' + zeroFill(d.getSeconds());
} else {
var s = (d.getMonth() + 1) + '/' + d.getDate() + '/' + d.getFullYear();
}
return s;
}
6) Tie it all together:
function parseDate(s) {
var d;
if (looksLikeMSDate(s))
d = parseMSDate(s);
else if (looksLikeIsoDate(s))
d = parseIsoDate(s);
else
return null;
return formatDate(d);
}
The below old answer is useful for tying this date formatting into jQuery's own JSON parsing so you get Date objects instead of strings, or if you're still stuck in jQuery <1.5 somehow.
Old Answer
If you're using jQuery 1.4's Ajax function with ASP.NET MVC, you can turn all DateTime properties into Date objects with:
// Once
jQuery.parseJSON = function(d) {return eval('(' + d + ')');};
$.ajax({
...
dataFilter: function(d) {
return d.replace(/"\\\/(Date\(-?\d+\))\\\/"/g, 'new $1');
},
...
});
In jQuery 1.5 you can avoid overriding the parseJSON method globally by using the converters option in the Ajax call.
http://api.jquery.com/jQuery.ajax/
Unfortunately you have to switch to the older eval route in order to get Dates to parse globally in-place - otherwise you need to convert them on a more case-by-case basis post-parse.
There is no built in date type in JSON. This looks like the number of seconds / milliseconds from some epoch. If you know the epoch you can create the date by adding on the right amount of time.
I also had to search for a solution to this problem and eventually I came across moment.js which is a nice library that can parse this date format and many more.
var d = moment(yourdatestring)
It saved some headache for me so I thought I'd share it with you. :)
You can find some more info about it here: http://momentjs.com/
I ended up adding the "characters into Panos's regular expression to get rid of the ones generated by the Microsoft serializer for when writing objects into an inline script:
So if you have a property in your C# code-behind that's something like
protected string JsonObject { get { return jsSerialiser.Serialize(_myObject); }}
And in your aspx you have
<script type="text/javascript">
var myObject = '<%= JsonObject %>';
</script>
You'd get something like
var myObject = '{"StartDate":"\/Date(1255131630400)\/"}';
Notice the double quotes.
To get this into a form that eval will correctly deserialize, I used:
myObject = myObject.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
I use Prototype and to use it I added
String.prototype.evalJSONWithDates = function() {
var jsonWithDates = this.replace(/"\/Date\((\d+)\)\/"/g, 'new Date($1)');
return jsonWithDates.evalJSON(true);
}
In jQuery 1.5, as long as you have json2.js to cover for older browsers, you can deserialize all dates coming from Ajax as follows:
(function () {
var DATE_START = "/Date(";
var DATE_START_LENGTH = DATE_START.length;
function isDateString(x) {
return typeof x === "string" && x.startsWith(DATE_START);
}
function deserializeDateString(dateString) {
var dateOffsetByLocalTime = new Date(parseInt(dateString.substr(DATE_START_LENGTH)));
var utcDate = new Date(dateOffsetByLocalTime.getTime() - dateOffsetByLocalTime.getTimezoneOffset() * 60 * 1000);
return utcDate;
}
function convertJSONDates(key, value) {
if (isDateString(value)) {
return deserializeDateString(value);
}
return value;
}
window.jQuery.ajaxSetup({
converters: {
"text json": function(data) {
return window.JSON.parse(data, convertJSONDates);
}
}
});
}());
I included logic that assumes you send all dates from the server as UTC (which you should); the consumer then gets a JavaScript Date object that has the proper ticks value to reflect this. That is, calling getUTCHours(), etc. on the date will return the same value as it did on the server, and calling getHours() will return the value in the user's local timezone as determined by their browser.
This does not take into account WCF format with timezone offsets, though that would be relatively easy to add.
Using the jQuery UI datepicker - really only makes sense if you're already including jQuery UI:
$.datepicker.formatDate('MM d, yy', new Date(parseInt('/Date(1224043200000)/'.substr(6))));
output:
October 15, 2008
Don't over-think this. Like we've done for decades, pass a numeric offset from the de-facto standard epoch of 1 Jan 1970 midnight GMT/UTC/&c in number of seconds (or milliseconds) since this epoch. JavaScript likes it, Java likes it, C likes it, and the Internet likes it.
Everyone of these answers has one thing in common: they all store dates as a single value (usually a string).
Another option is to take advantage of the inherent structure of JSON, and represent a date as list of numbers:
{ "name":"Nick",
"birthdate":[1968,6,9] }
Of course, you would have to make sure both ends of the conversation agree on the format (year, month, day), and which fields are meant to be dates,... but it has the advantage of completely avoiding the issue of date-to-string conversion. It's all numbers -- no strings at all. Also, using the order: year, month, day also allows proper sorting by date.
Just thinking outside the box here -- a JSON date doesn't have to be stored as a string.
Another bonus to doing it this way is that you can easily (and efficiently) select all records for a given year or month by leveraging the way CouchDB handles queries on array values.
Posting in awesome thread:
var d = new Date(parseInt('/Date(1224043200000)/'.slice(6, -2)));
alert('' + (1 + d.getMonth()) + '/' + d.getDate() + '/' + d.getFullYear().toString().slice(-2));
Just to add another approach here, the "ticks approach" that WCF takes is prone to problems with timezones if you're not extremely careful such as described here and in other places. So I'm now using the ISO 8601 format that both .NET & JavaScript duly support that includes timezone offsets. Below are the details:
In WCF/.NET:
Where CreationDate is a System.DateTime; ToString("o") is using .NET's Round-trip format specifier that generates an ISO 8601-compliant date string
new MyInfo {
CreationDate = r.CreationDate.ToString("o"),
};
In JavaScript
Just after retrieving the JSON I go fixup the dates to be JavaSript Date objects using the Date constructor which accepts an ISO 8601 date string...
$.getJSON(
"MyRestService.svc/myinfo",
function (data) {
$.each(data.myinfos, function (r) {
this.CreatedOn = new Date(this.CreationDate);
});
// Now each myinfo object in the myinfos collection has a CreatedOn field that is a real JavaScript date (with timezone intact).
alert(data.myinfos[0].CreationDate.toLocaleString());
}
)
Once you have a JavaScript date you can use all the convenient and reliable Date methods like toDateString, toLocaleString, etc.
var newDate = dateFormat(jsonDate, "mm/dd/yyyy");
Is there another option without using the jQuery library?
This may can also help you.
function ToJavaScriptDate(value) { //To Parse Date from the Returned Parsed Date
var pattern = /Date\(([^)]+)\)/;
var results = pattern.exec(value);
var dt = new Date(parseFloat(results[1]));
return (dt.getMonth() + 1) + "/" + dt.getDate() + "/" + dt.getFullYear();
}
I get the date like this:
"/Date(1276290000000+0300)/"
In some examples the date is in slightly different formats:
"/Date(12762900000000300)/"
"Date(1276290000000-0300)"
etc.
So I came up with the following RegExp:
/\/+Date\(([\d+]+)\)\/+/
and the final code is:
var myDate = new Date(parseInt(jsonWcfDate.replace(/\/+Date\(([\d+-]+)\)\/+/, '$1')));
Hope it helps.
Update:
I found this link from Microsoft:
How do I Serialize Dates with JSON?
This seems like the one we are all looking for.
Below is a pretty simple solution for parsing JSON dates. Use the below functions as per your requirement. You just need to pass the JSON format Date fetched as a parameter to the functions below:
function JSONDate(dateStr) {
var m, day;
jsonDate = dateStr;
var d = new Date(parseInt(jsonDate.substr(6)));
m = d.getMonth() + 1;
if (m < 10)
m = '0' + m
if (d.getDate() < 10)
day = '0' + d.getDate()
else
day = d.getDate();
return (m + '/' + day + '/' + d.getFullYear())
}
function JSONDateWithTime(dateStr) {
jsonDate = dateStr;
var d = new Date(parseInt(jsonDate.substr(6)));
var m, day;
m = d.getMonth() + 1;
if (m < 10)
m = '0' + m
if (d.getDate() < 10)
day = '0' + d.getDate()
else
day = d.getDate();
var formattedDate = m + "/" + day + "/" + d.getFullYear();
var hours = (d.getHours() < 10) ? "0" + d.getHours() : d.getHours();
var minutes = (d.getMinutes() < 10) ? "0" + d.getMinutes() : d.getMinutes();
var formattedTime = hours + ":" + minutes + ":" + d.getSeconds();
formattedDate = formattedDate + " " + formattedTime;
return formattedDate;
}
You also can use the JavaScript library moment.js, which comes in handy when you plan do deal with different localized formats and perform other operations with dates values:
function getMismatch(id) {
$.getJSON("Main.aspx?Callback=GetMismatch",
{ MismatchId: id },
function (result) {
$("#AuthMerchId").text(result.AuthorizationMerchantId);
$("#SttlMerchId").text(result.SettlementMerchantId);
$("#CreateDate").text(moment(result.AppendDts).format("L"));
$("#ExpireDate").text(moment(result.ExpiresDts).format("L"));
$("#LastUpdate").text(moment(result.LastUpdateDts).format("L"));
$("#LastUpdatedBy").text(result.LastUpdateNt);
$("#ProcessIn").text(result.ProcessIn);
}
);
return false;
}
Setting up localization is as easy as adding configuration files (you get them at momentjs.com) to your project and configuring the language:
moment.lang('de');
Check up the date ISO standard; kind of like this:
yyyy.MM.ddThh:mm
It becomes 2008.11.20T22:18.
This is frustrating. My solution was to parse out the "/ and /" from the value generated by ASP.NET's JavaScriptSerializer so that, though JSON may not have a date literal, it still gets interpreted by the browser as a date, which is what all I really want:{"myDate":Date(123456789)}
Custom JavaScriptConverter for DateTime?
I must emphasize the accuracy of Roy Tinker's comment. This is not legal JSON. It's a dirty, dirty hack on the server to remove the issue before it becomes a problem for JavaScript. It will choke a JSON parser. I used it for getting off the ground, but I do not use this any more. However, I still feel the best answer lies with changing how the server formats the date, for example, ISO as mentioned elsewhere.
A late post, but for those who searched this post.
Imagine this:
[Authorize(Roles = "Administrator")]
[Authorize(Roles = "Director")]
[Authorize(Roles = "Human Resources")]
[HttpGet]
public ActionResult GetUserData(string UserIdGuidKey)
{
if (UserIdGuidKey!= null)
{
var guidUserId = new Guid(UserIdGuidKey);
var memuser = Membership.GetUser(guidUserId);
var profileuser = Profile.GetUserProfile(memuser.UserName);
var list = new {
UserName = memuser.UserName,
Email = memuser.Email ,
IsApproved = memuser.IsApproved.ToString() ,
IsLockedOut = memuser.IsLockedOut.ToString() ,
LastLockoutDate = memuser.LastLockoutDate.ToString() ,
CreationDate = memuser.CreationDate.ToString() ,
LastLoginDate = memuser.LastLoginDate.ToString() ,
LastActivityDate = memuser.LastActivityDate.ToString() ,
LastPasswordChangedDate = memuser.LastPasswordChangedDate.ToString() ,
IsOnline = memuser.IsOnline.ToString() ,
FirstName = profileuser.FirstName ,
LastName = profileuser.LastName ,
NickName = profileuser.NickName ,
BirthDate = profileuser.BirthDate.ToString() ,
};
return Json(list, JsonRequestBehavior.AllowGet);
}
return Redirect("Index");
}
As you can see, I'm utilizing C# 3.0's feature for creating the "Auto" Generics. It's a bit lazy, but I like it and it works.
Just a note: Profile is a custom class I've created for my web application project.
FYI, for anyone using Python on the server side: datetime.datetime().ctime() returns a string that is natively parsable by "new Date()". That is, if you create a new datetime.datetime instance (such as with datetime.datetime.now), the string can be included in the JSON string, and then that string can be passed as the first argument to the Date constructor. I haven't yet found any exceptions, but I haven't tested it too rigorously, either.
Mootools solution:
new Date(Date(result.AppendDts)).format('%x')
Requires mootools-more. Tested using mootools-1.2.3.1-more on Firefox 3.6.3 and IE 7.0.5730.13
var obj = eval('(' + "{Date: \/Date(1278903921551)\/}".replace(/\/Date\((\d+)\)\//gi, "new Date($1)") + ')');
var dateValue = obj["Date"];
Add the jQuery UI plugin in your page:
function DateFormate(dateConvert) {
return $.datepicker.formatDate("dd/MM/yyyy", eval('new ' + dateConvert.slice(1, -1)));
};
What if .NET returns...
return DateTime.Now.ToString("u"); //"2013-09-17 15:18:53Z"
And then in JavaScript...
var x = new Date("2013-09-17 15:18:53Z");

Categories

Resources