C# is kicking my butt...
I have a text file I'm splitting in hopes to insert into SQL. I need a swift shove in the right direction!
An excerpt from the file I am capturing is below and I am splitting on " - "
2020-06-25-13.23.04.220000 - Running MRP for Site
I can split the two parts just fine.
console_output
But can't seem to get the date into a format that is valid for my SQL insert. I think, but could be completely wrong that I need to reformat this date string using some REPLACE commands.
If I try and use DateTime.ParseExact using my non-working code below I receive a System.FormatException:String was not recognized as valid on my DateTime.ParseExact line.
foreach (string line in lines)
{
if (line.Contains("Running MRP for Site"))
{
List<string> s = new List<string>(
line.Split(new string[] { " - " }, StringSplitOptions.None));
Console.WriteLine(s[0].ToString());
Console.WriteLine(s[1].ToString());
string format = "yyyy-MM-dd-hh:mm:ss:ffffff";
string date = s[0].ToString().Replace('.', ':');
DateTime dt = DateTime.ParseExact(date, format, CultureInfo.InvariantCulture);
/*
if (conn.State != ConnectionState.Open)
{
conn = new SqlConnection { ConnectionString = Properties.Settings.Default.ConnectionString };
conn.Open();
}
{
String query = #"INSERT INTO
It's the hh. That's a 12-hour clock. You need HH for a 24-hour clock. See Custom date and time format strings - the "HH" custom format specifier.
Here it is in the form of a unit test that takes the input string and verifies that the result is correct (although perhaps crudely.)
[TestMethod]
public void ParseDateTimeTest()
{
var input = "2020-06-25-13.23.04.220000 - Running MRP for Site";
var firstSegment = input.Split(new string[] { " - " }, StringSplitOptions.None)[0];
string format = "yyyy-MM-dd-HH.mm.ss.ffffff";
var parsed = DateTime.ParseExact(firstSegment, format, CultureInfo.InvariantCulture);
Assert.AreEqual(13, Math.Truncate((parsed - new DateTime(2020, 6, 25)).TotalHours));
}
Related
When I try this code:
string value = "220510"; // The `value` variable is always in this format
string key = "30";
string title;
switch (key)
{
case "30":
title = "Date: ";
Console.WriteLine($"{title} is {value}");
break;
}
the output looks like this:
My problem is that I don't know how to insert the '-' character to separate the month, day and year because I want it to display:
Date: is 22-05-10
Please show me how to parse it.
If you have a DateTime object:
oDate.toString("yy-MM-dd");
If you have a string you can either:
sDate = sDate.Insert(2,"-");
sDate = sDate.Insert(5,"-");
or go through DateTime again (for whatever reason):
string sDate = "220510";
CultureInfo provider = CultureInfo.InvariantCulture;
DateTime sDate = Convert.ParseExact(iDate, "yyMMdd", provider);
sDate.toString("yy-MM-dd");
Your question is: How do I parse the string 220510 date format so the value comes out as 22-05-10?
In this specific case, consider using the string.Substring method to pick out the digit pairs then use string interpolation to put them back together.
const string raw = "220510";
// To do a simple parse (not using a DateTime object)
var yearString = raw.Substring(0, 2);
var monthString = raw.Substring(2, 2);
var dayString = raw.Substring(4, 2);
var string_22_05_10 = $"{yearString}-{monthString}-{dayString}";
Console.WriteLine(string_22_05_10);
I have a string variable with the value of 07/31/2016 and I need to convert this to show as July 2016. How can I do this in C#?
var input = "07/31/2016";
var date = DateTime.Parse(input);
var output = date.ToString("MMMM-yyyy");
See DateTime.Parse.
See also date and time format strings.
CultureInfo provider = CultureInfo.InvariantCulture;
var input = "07/31/2016";
var date = DateTime.ParseExact(input,"MM/dd/yyyy",provider);
var output = date.ToString("MMMM-yyyy");
This should be work:
string iDate = "07/31/2016";
DateTime oDate = Convert.ToDateTime(iDate);
Console.WriteLine(CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(oDate.Month) + " " + oDate.Year);
Parse to DateTime and call ToString() with the new format.
I have a small question.
I have to get only the Ship date "July 17, 2015" from the string. lets say this is my code:
string result = "";
foreach (HtmlElement el in webBrowser1.Document.GetElementsByTagName("div"))
if (el.GetAttribute("className") == "not-annotated hover")
{
result = el.InnerText;
textBox2.Text = result;
}
Now this is the output:
string result = "";
string date = "";
foreach (HtmlElement el in webBrowser1.Document.GetElementsByTagName("div"))
if (el.GetAttribute("className") == "not-annotated hover")
{
result = el.InnerText;
date = Regex.Match(result ,
String.Format(#"{0}\s(?<words>[\w\s]+)\s{1}", "Ship Date:", "Country:"),
RegexOptions.IgnoreCase).Groups["words"].Value;
textBox2.Text = date ;
}
It seems as if your div is an outer div, you need the one which displays the ship-date only. That would be the safest/easiest approach.
However, if all you have is that large string, you could split by new-line characters and get the date from the line which starts with Ship date:
string[] lines = result.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
string dateString = lines
.FirstOrDefault(l => l.Trim().StartsWith("Ship date", StringComparison.InvariantCultureIgnoreCase));
DateTime shipDate;
if (dateString != null)
{
string[] formats = new[] { "MMMM dd, yyyy" };
string datePart = dateString.Split(':').Last().Trim();
bool validShipDate = DateTime.TryParseExact(
datePart,
formats,
DateTimeFormatInfo.InvariantInfo,
DateTimeStyles.None,
out shipDate);
if (validShipDate)
Console.WriteLine(shipDate);
}
From the Output text that you have shared,
string result = "";
foreach (HtmlElement el in webBrowser1.Document.GetElementsByTagName("div"))
if (el.GetAttribute("className") == "not-annotated hover")
{
result = el.InnerText;
if (result.IndexOf("Ship Date") == 0) //Ship Date text is present in the string
{
//since the string format is Ship Date: July 17, 2015 -
//we can assume : as a delimiter and split the text
string[] splitText = result.Split(':');
string date = splitText[1].Trim(); //this will give the date portion alone
}
textBox2.Text = result;
}
Hope this helps.
NOTE: This logic will work only if the Ship Date string in the HTML is received in the same format as specified in your Output sample
so I understand how to make global values and the fact that 1. you shouldn't do it and 2. you cannot use a value that was created in a different "context" however, I'm not sure how to correct this problem in my case. I think it will make sense if you read my code
//read in Load Query TestCSV
var sourcePath = #"D:\\Load Query test.csv"; //What is the inital CSV
var delimiter = ",";
var firstLineContainsHeaders = true; //CSV has headers
//creates temp file which takes less time than loading into memory
var tempPath = Path.Combine(#"D:", Path.GetRandomFileName());
var lineNumber = 0;
var splitExpression = new Regex(#"(" + delimiter + #")(?=(?:[^""]|""[^""]*"")*$)");
using (var writer = new StreamWriter(tempPath))
using (var reader = new StreamReader(sourcePath))
{
string line = null;
string[] headers = null;
if (firstLineContainsHeaders)
{
line = reader.ReadLine();
lineNumber++;
if (string.IsNullOrEmpty(line)) return; // file is empty;
headers = splitExpression.Split(line).Where(s => s != delimiter).ToArray();
writer.WriteLine(line); // write the original header to the temp file.
}
var i = 0; //used in 2nd while loop later
string lines = null;//used in next using statement
while ((line = reader.ReadLine()) != null)
{
lineNumber++;
var columns = splitExpression.Split(line).Where(s => s != delimiter).ToArray();
//make sure you always have the same number of columns in a line
if (headers == null) headers = new string[columns.Length];
if (columns.Length != headers.Length) throw new InvalidOperationException(string.Format("Line {0} is missing one or more columns.", lineNumber));
string badDate = "Date entered incorrectly"; //used in next while loop
// this while loop will read in the user input dateTime and use that to get the column from the PI server.
//if the date time is entered incorrectly it will tell the user to try to input the datetime again
while (i==0)
{
Console.WriteLine("Enter date, ex:16 Jun 8:30 AM 2008, Press enter when done"); //instruct the user in how to enter the date
string userInput = Console.ReadLine(); //read in the date the user enters
string format = "dd MMM h:mm tt yyyy"; //how the system will read the date entered
DateTime dateTime;
//if date is entered correctly, parse it, grab the parsed value dateTime and exit loop
if (DateTime.TryParseExact(userInput, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime))
{
i = 1; //set the flag to exit while loop
}
//if input is bad return "Date entered incorrectly and run the loop again
else
{
Console.WriteLine(badDate);
i=0; //set the flag to run the loop again
}
}
var del = ","; //used in next using statement
var SplitExpression = new Regex(#"(" + del + #")(?=(?:[^""]|""[^""]*"")*$)"); //used in next using statement
//Use the dateTime from the previous while loop and use it to add each point in "testpts.csv" to "Load Query Test.csv"
using (StreamReader tags = new StreamReader(#"D:\\testpts.csv"))
{
// string userInput = Console.ReadLine();
string format = "dd MMM h:mm tt yyyy";
DateTime.TryParseExact(userInput, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);
lines = tags.ReadLine();
var columns1 = SplitExpression.Split(lines).Where(s => s != del).ToArray();
var point = PIPoint.FindPIPoint(piServer, lines);
var value = point.RecordedValue(dateTime);
string returnXml = string.Format(#"<value=""{0}"" />", value);
columns[15] = columns[15].Replace("0", returnXml); //column the point should be placed in (in Load Query Test.csv)
}
//if statement that will replace any extra 0 testpt values with column 13 values
if (columns[15].Contains("0"))
{
columns[15] = columns[15].Replace("0", columns[13]);
}
writer.WriteLine(string.Join(delimiter, columns));
}
}
File.Delete(sourcePath); //delete the original csv
File.Move(tempPath, sourcePath); //replace the old csv with edited one
Console.ReadLine();
I'm getting the error in the using statement:
using (StreamReader tags = new StreamReader(#"D:\\testpts.csv"))
{
// string userInput = Console.ReadLine();
string format = "dd MMM h:mm tt yyyy";
DateTime.TryParseExact(userInput, format, CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);
lines = tags.ReadLine();
var columns1 = SplitExpression.Split(lines).Where(s => s != del).ToArray();
var point = PIPoint.FindPIPoint(piServer, lines);
var value = point.RecordedValue(dateTime);
string returnXml = string.Format(#"<value=""{0}"" />", value);
columns[15] = columns[15].Replace("0", returnXml); //column the point should be placed in (in Load Query Test.csv)
}
In this case the dateTime and userInput values are obviously out of context. I need them created in the previous while loop however because I want the user to be able to enter the correct date only once and ensure that it is entered correctly to make sure the script will actually pull data.
Please let me know if there is another way I can order my code or how I can make userInput and dateTime global. Thank you
Your problem lies in the "dateTime" variable. "userInput" is fine, the inner using statement has access to the scope of its outer using statement, because the inner one is part of the outer's scope.
The problem is with "dateTime" - the variable is declared inside a while loop, and there is a using block afterwards - after the variable is not available anymore, because the scope was disposed - which references a non existent variable.
Solution: move the declaration of your dateTime variable out of the while. Say, a line before the while's definition.
Without critisizing your code to much ... here an answer. You should be able to walk yourself from here on
Split the declaration of the variable with it's assignment
string userInput = Console.ReadLine();
to
string userInput;
userInput = Console.ReadLine();
Move the declarations (the first line) outside of the outer Loop.
Edit: Please, also have a look at Properties (you may call them
globals)
I am reading date/time and data from a csv file and store this in a line chart. My date/time string is 1-1-2014 21:55:42 or 18-02-2014 00:00:00 which is actually the first entry and i have for a couple of hours data.
First i'm setting the chartArea X axis lablestyle to the proper format: "d-M-yyyy HH:mm:ss".
Then i parse my actual date string to a DateTime format using the same format as above: d-M-yyyy HH:mm:ss. And add the data to the chart.
I ensure you my date is correct:
And my code:
private void button2_Click_1(object sender, EventArgs e)
{
string line;
char[] delimiters = { ';', ',', '|' };
chart1.Series["Series1"].XValueType = ChartValueType.Time;
chart1.ChartAreas["ChartArea1"].AxisX.LabelStyle.Format = "d-M-yyyy HH:mm:ss";
chart1.Series["Series1"].Points.Clear();
using (System.IO.StreamReader sr = new System.IO.StreamReader(filename))
{
while (!sr.EndOfStream)
{
line = sr.ReadLine();
DateTime newDateTime = new DateTime();
string[] part = line.Split(delimiters);
Console.WriteLine(part[0]);
newDateTime = DateTime.ParseExact(
part[0],
"d-M-yyyy HH:mm:ss",
CultureInfo.InvariantCulture
);
chart1.Series["Series1"].Points.AddXY(newDateTime, part[5]);
}
}
chart1.Refresh();
}
Problem : You have set the Custom Format for X-Axis as d-M-yyyy HH:mm:ss but you are just providing the datetime without formatting it.
Replace This:
chart1.Series["Series1"].Points.AddXY(newDateTime, part[5]);
With This:
chart1.Series["Series1"].Points.AddXY(
newDateTime.ToString("d-M-yyyy HH:mm:ss"), part[5]);