I'm getting parse exceptions when using WindowsAzure.Storage to access storage analytics logs.
This is my code for retrieving log records:
var recordList = this.SourceAnalyticsClient.ListLogRecords(
this.Service, this.StartTime, null, this.Configuration.BlobRequestOptions,
this.CreateOperationContext())
.ToList();
That code throws the following exception:
Error parsing log record: could not parse 'Wednesday, 03-Dec-14 08:59:27 GMT' using format: dddd, dd-MMM-yy HH:mm:ss 'GMT' (type InvalidOperationException)
Exception stack trace:
at Microsoft.WindowsAzure.Storage.Analytics.LogRecordStreamReader.ReadDateTimeOffset(String format)
at Microsoft.WindowsAzure.Storage.Analytics.LogRecord.PopulateVersion1Log(LogRecordStreamReader reader)
at Microsoft.WindowsAzure.Storage.Analytics.LogRecord..ctor(LogRecordStreamReader reader)
I'm guessing this happens because my thread is not using an English culture.
I need a way to resolve this problem or a workaround.
After investing this a little bit I found that LogRecordStreamReader.ReadDateTimeOffset is specifying a null format provider parameter to DateTimeOffset.TryParseExact. That means that the thread's current culture will be used - and that won't work for threads using non-English cultures.
A possible workaround is:
// Remember current culture setting
CultureInfo originalThreadCulture = Thread.CurrentThread.CurrentCulture;
try
{
// Assign the invariant culture temporarily
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
// Let WindowsAzure.Storage parse log records
recordList = this.SourceAnalyticsClient.ListLogRecords(
this.Service, this.StartTime, null, this.Configuration.BlobRequestOptions,
this.CreateOperationContext())
.ToList();
}
finally
{
// Restore original culture setting
Thread.CurrentThread.CurrentCulture = originalThreadCulture;
}
I've also created a pull request with a suggested fix.
Related
I followed roughly this example to backup a database with Microsofts SMO API and the code crashed with an exception telling invalid parameter ExpirationDate. I checked the documentation which does not contain details on how to set the parameter and my intuition told me it should be in the future, right? I was curious and tested some values:
DateTime.Today.AddDays(10) -> InvalidDataException
DateTime.Today.AddDays(-10) -> works fine
DateTime.Today.AddDays(-5) -> works fine
DateTime.Today.AddDays(-4) -> works fine
DateTime.Today.AddDays(-3) -> InvalidDataException
DateTime.Today.AddDays(-1) -> InvalidDataException
DateTime.Today.AddDays(100) -> InvalidDataException
DateTime.Today.AddDays(500) -> InvalidDataException
DateTime.Today.AddDays(1000) -> works fine
Reading this 5 year-old post it could be that the internal parameter is actually not of the type DateTime? But then it would be a bug, right?
These errors are likely the result of the locale of where the Backup.ExpirationDate property is being set from. Depending on the culture this is being executed in, the DateTime.AddDays method may increment the month instead of the day as expected, leading to the inconsistent results you saw. Of the values that you tested only the negative ones should cause errors, as the range of days for a backup expiration date is 0 - 99999, with 0 indicating that the backup will never expire as stated in the documentation. Try using the CultureInfo class to define a new locale then set the expiration date. This will require a reference to the System.Globalization namespace. Running the following code gave me no errors in setting the expiration date in a backup operation using the US (en-US) culture. Just make sure that the date in the culture you convert this to matches the date you expect it to in your timezone.
using System.Globalization;
string folderPath = #"C:\YourFolder\";
Server serv = new Server(#"YourServer");
Backup bkup = new Backup();
bkup.Database = "YourDatabase";
string bkupFilePath = folderPath + bkup.Database.ToString() + ".bak";
bkup.Action = BackupActionType.Database;
bkup.Devices.AddDevice(bkupFilePath, DeviceType.File);
bkup.BackupSetName = "YourDatabase Full Backup";
bkup.BackupSetDescription = "Full backup of YourDatabase";
DateTime today = DateTime.Now;
//define current date representation with en-US culture
string newLocale = today.ToString(new CultureInfo("en-US"));
//set Backup.ExpirationDate to use new culture
bkup.ExpirationDate = Convert.ToDateTime(newLocale);
bkup.ExpirationDate.AddDays(10);
bkup.ExpirationDate.AddDays(100);
bkup.ExpirationDate.AddDays(500);
bkup.ExpirationDate.AddDays(1000);
bkup.SqlBackup(serv);
edit I am super confused. I thought this solved my issue:
My issue was that I called backup.ExpirationDate.AddDays(X) without assigning it to anything. Therefore, the software was basically using "DateTime.Now".
Solution:
backup.ExpirationDate = backup.ExpirationDate.AddDays(X);
But it didn't completely. I still get the exception if I do this:
backup.ExpirationDate = backup.ExpirationDate.AddDays(1);
No idea why this code is wrong.
I have written a C# console application that after all of it's processing outputs a DateTime to disk. It does this like so:
writer.WriteLine(myDateTime).
This same console appication has no problems with using the following to read this DateTime back:
DateTime.Parse(reader.ReadLine())
However, upon attempting to use the following code in my separate Asp.Net program I recieve an error saying that my string is not a valid DateTime which is odd to say the least.
StreamReader reader = new StreamReader(#"D:\InformerReports\Archive\ReliabilityData\StartTime.hist");
string dateString = reader.ReadLine();
return DateTime.Parse(dateString);
I have checked and the string it is reading in is 10/25/2016 12:00:00 AM.
I have also attempted to use return DateTime.ParseExact(dateString, "dd/MM/yyyy hh:mm:ss tt",null) but this returns the same error.
I can't seem to fathom why identical code performed on the same file works in one case and not the other. I'd appreciate some help.
I guess the culture of the server is different from the machine you are testing from.
The correct format you have to use seems to be:
return DateTime.ParseExact(dateString, "MM/dd/yyyy hh:mm:ss tt", null)
// 10/25/2016 12:00:00 AM
As an add-on to the previous answers.
To avoid the differing cultures across clients you can set the site culture in the global.asax files Application_BeginRequest method like below:
Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fr-FR");
Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fr-FR");
This will force the above specified culture for each user accessing the site.
I am not sure if there are drawbacks to doing it this way, but this solved my issue in the past.
My problem is related to this question:
I'm having the same failure, but in a different scenario:
At run time the error is occurring inside;
using (var scope = new TransactionScope())
{
// Doing stuff here fails only within a transaction!
scope.Complete();
}
The same problem code runs perfectly fine when executed outside of a transaction!
The error message is:
Newtonsoft.Json.JsonReaderException was unhandled
HResult=-2146233088 LineNumber=1 LinePosition=33 Message=Could
not convert string to DateTime: 15/05/2016 09:23:34 +00:00. Path 'a',
line 1, position 33. Path=a Source=Neo4jClient
The code versions are:
Neo4jClient version=1.1.0.16
Newtonsoft.Json version=8.0.1
This answer basically says I can pass a
new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" }
To the serialisation but as that is inside Neo4jClient how can I implement that.
Answer
client.JsonConverters.Add( new IsoDateTimeConverter() );
Adding this line of code immediately after creating the client, solved the of datetime serialisation problem.
Note: my culture is en-GB so I am not sure if this would need finegling to adjust for your culture settings.
client.JsonConverters.Add( new IsoDateTimeConverter() );
I think there are numerous ways of making this happen but this one definately works.
I have a textbox with value that stores ValidFrom form value:
31.01.2012
and cultures set to:
<globalization culture="en-GB" uiCulture="en-GB"/>
in web.config.
And now, ObjectDataSource update method:
public static void UpdateLac(int id, DateTime ValidFrom)
{
/// ...
}
fails as I get exception that string cannot be parsed. However date in format dd.mm.yyyy (31.01.2012) is valid en-GB format and can be parsed (as far as I know). I have tested it with following code:
DateTimeFormatInfo dtfi = CultureInfo.CreateSpecificCulture("en-GB").DateTimeFormat;
var date = DateTime.Parse("31.01.2012", dtfi);
Console.Write(date.ToLongDateString());
So how come that ObjectDataSource internal conversion fails to convert string (31.01.2012) to DateTime in this example?
As far as I know the culture info is loaded directly from the OS ( in this case windows), you can check on your regional setting for the format specified. This is a screenshot from my pc:
http://imageshack.us/photo/my-images/96/engbg.png/
As you can see the format for short date is: dd/MM/aa, so maybe there is something going on with your server regional settings or the input should be: 31/01/12 instead of 31.01.2012
Hope this helps.
I am inserting some data into a SharePoint list (via web services) and on my local machine I set a date field like this (hard coded in this example)
<Field Name='TimeOnScene'>" + DateTime.Parse("13/12/2011 1:00").ToString("yyyy-MM-ddTHH:mm:ssZ") + "</Field>
and it works fine on my local machine, but if I publish it to our web host and run the exact same code I get
{"Message":"String was not recognized as a valid DateTime.","StackTrace":"
//
//
System.DateTimeParse.Parse(String s, DateTimeFormatInfo dtfi, DateTimeStyles styles)\r\n at System.DateTime.Parse(String s)\r\n "ExceptionType":"System.FormatException"}
How is this possible?
Thanks in advance.
Edit:
we also moved from host to another two weeks ago and never had this issue before.
Use DateTime.ParseExact instead of Parse, the converting will be like the following code.
CurDate = DateTime.ParseExact(YourDateString, "dd/MM/yyyy hh:mm", System.Globalization.CultureInfo.CurrentCulture, System.Globalization.DateTimeStyles.None)
The host could have different local in set on there machine. in the documentation
The string s is parsed using formatting information in the current DateTimeFormatInfo object, which is supplied implicitly by the current thread culture.