My input is an annoying free text in which I need to extract the date. This date could be present in any of the formats with anomalies.
eg. This is 9.9.12 date
This is 9912 date
This is 0992012 date
Any possible format.
dMy
ddMMyy
ddMMyyyy
Mdyy etc..
I am able to validate if the text is in date format for ddMMy* but not any other. I was looking into this https://www.c-sharpcorner.com/blogs/date-and-time-format-in-c-sharp-programming1 link to see what other formats could be possible but I got no leads.
Is this correct to write like in the following method for a date format say - 9912?
Date.ParseExact(test.ToString,"dMy", Globalization.CultureInfo.InvariantCulture)
If yes, the system is populating me the following err:
System.FormatException: String was not recognized as a valid DateTime.
Can anyone please share a reliable approach to tackle such problems?
There is no single way to accomplish what you're trying to do. Specifically, because the intent is so broad, it becomes hard to infer what the user actually means (e.g. how do you differentiate month vs. day).
Depending on how you're implementing your application, you need to implement input validation.
For a console app, I can envision you using something like:
if (DateTime.TryParse(line, out value))
{
// Parse-able date.
}
else
{
// Non-parseable date.
}
If you're building a WPF application, you can use binding validation. If you're building an ASP.NET MVC application, you can also implement model validation. Your mileage may vary - you should definitely consider constraining what your users can feed the application.
I am using the C# Object Persistence model in my application, and am populating the table from an external source. I insert a row with the following date (in a String column): 2018-12-12T22:27:14.73Z. This is generated from a Timestamp using the following Go code:
&dynamodb.AttributeValue{S: aws.String(entity.TimeStamp.UTC().Format("2006-01-02T15:04:05.999Z"))}
However, the DynamoDB Object Persistence model chokes when trying to convert it to a System.DateTime, with the following error: System.InvalidOperationException: Unable to convert [2018-12-12T22:27:14.73Z] of type Amazon.DynamoDBv2.DocumentModel.Primitive to System.DateTime
If I let my service write a System.DateTime (using a POCO that contains a DateTime property), it looks something like this: 2018-12-19T07:45:36.431Z. What am I missing that prevents AWS from properly deserializing my dates? It looks like I'm writing them in the same format that Amazon is writing them?
Ok, I found the answer. DynamoDB expects the column to always have 3 digits of precision in the fractional part of the timestamp. When I formatted the time from Golang, I used "2006-01-02T15:04:05.999Z" as my format string, but this causes time.Format to truncate the trailing zeros (when they exist). Changing my time format string to always print the full precision, I was able to fix my issues.
That said, the documentation could be a little more clear about this precision requirement. Or the exception could be a little more explicit. Heres hoping this question/answer makes that exception searchable on Google!
I have an MVC Web-API application for inner use. I have some pages with forms and numeric fields. I need to install this on a German computer, and the users will be only Germans. In Germany they write "3,5" instead of "3.5" (with a comma).
In IIS configuration the culture is "Invariant culture" and since the computer is German - the localize is "de-DE".
When the users write "3,5" in the field - I can see in firebug that "3,5" is what is sent in JSON, but the server gets it as "35".
Can I handle it on server-side? (I don't want to change the json because I'll need to do it in every field and page)
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
public class ItemsController : ApiController, IDisposable
{
[Authorize(Roles = "Admin")]
[HttpPost]
public HttpResponseMessage UpdateItem(ItemViewModel itemVM)
{
// JSON data sent data.NumProp1 = "3,5"
// itemVM.NumProp1 contains "35" instead of "3.5"
}
}
You should not localize your JSON - see http://www.json.org for the spec (which only shows the dot as a separator) and How to localize when JSON-serializing? for a similar question.
I wouldn't recommend trying to read your customized JSON - it may sound like a quick win right now, but in the end you simply aren't using JSON.
You must use CultureInfo.InvariantCulture on all your string formating calls when handling persitence (and JSON exchanges are technically a form of persitence):
Persisting Data
The InvariantCulture property can be used to persist data in a
culture-independent format. This provides a known format that does not
change and that can be used to serialize and deserialize data across
cultures. After the data is deserialized, it can be formatted
appropriately based on the cultural conventions of the current user.
For example, if you choose to persist date and time data in string
form, you can pass the InvariantCulture object to the
DateTime.ToString(String, IFormatProvider) or
DateTimeOffset.ToString(IFormatProvider) method to create the string,
and you can pass the InvariantCulture object to the
DateTime.Parse(String, IFormatProvider) or
DateTimeOffset.Parse(String, IFormatProvider, DateTimeStyles) method
to convert the string back to a date and time value. This technique
ensures that the underlying date and time values do not change when
the data is read or written by users from different cultures.
This applies to all types: numerics, decimals, floats and doubles, date and time etc. Use the invariant culture both when writing and when reading serialized data. Use invariant culture on both sides of a JSON exchange.
BTW, if you'd use the built-in JSON serializers, you'd already get this lunch for free: JsonWriter.cs, JsonReader.cs.
As already said: JSON is a standard, and you should never deviate from the standard. Doing that will make your life miserable.
If the users enter some numbers in a web form, that web form should serialize that in the correct JSON format. I think usually that is done already, if you use the right numeric types in your form, like input type='number', etc. On the server end, you should read it using the InvariantCulture.
This need for a general solution is acknowledged by the W3C, as you can see in the draft W3C HTML JSON form submission.
In addition to the other answers, if you want to just replace the German "," decimal separator with the current culture one, which makes the conversion parse correctly, use:
str = str.Replace(",", System.Globalization.CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator);
You can then convert your string into a numeric value using stuff like Convert.ToInt32
I'm probably blind to something right in front of me.
But In my MVC application, I have an object/model that has a DateTime property.
I do an AJAX GET to retrieve the model. The datetime when received looks something like Date(142342323).
I want to convert this date to the locale setting of the user. In moment.js I don't see a way to set it to local.
I thought about getting the currentculture in MVC and passing that as a value (and storing it as an hidden field on the page ) and then using that for the javascript date format...but there seems to be a discrepancy between c# formats and javascript formats.
Ideas anyone?
I mainly have 1 format for Europe and 1 for US (dd/mm/yyyy and mm/dd/yyyy).
How is formatted user input typically handled in an MVC application? A user entering "1,000.00" for a number for example. I'm somewhat surprised the default ModelBinder does not pick up on this. Would this be the type of thing I would create my own ModelBinder for?
I think that DefaultModelBinder use CultureInfo.CurrentCulture to parse numeric data.