Search code examples
c#regexdatetimewritetofiletryparse

Extra zero's being added when writing to file in C#


I have a csv file with certain records in it. Within these records are dates in various formats. I want to transform all of the formats into MM/dd/yyyy, where there is a 0 in front of any single digit month or day. The problem is that when it writes to the file it's adding a bunch of extra 0's and I cannot figure out why. An example of my data is:

Title,Labels,Type,Current State,Created at,Accepted at,Deadline,Requested By,Description,Owned By,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment,Comment
pad,pad,epic,,9/26/2012 0:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655656 add security role xxxx,user updates,chore,accepted,7/20/2012 0:00,7/23/2012 0:00,,xxxx,"Call Number: 655656 
Client Name: xxxxx
Department: 
Address: xxxx
Phone: (xxx)xxx-xxxx
Open Date/Time: 6/25/2012 2:50:52 PM
Opened by: MAGIC 

Problem Description: Effective Date: 07/09/2012 12:00 a       
Area: CASE COMPASS.
Action: ADD ACCESS
Report/other Role: NONE
App Role: FIELD()

xxxx 7/18/2012 9:17 AM: created user id and assigned roles in enterprise security 

Notes:  

Problem Resolution: 7/19/12 - xxxx: Access granted, AD account added to the HL_Viewer security group.

CDS\xxxx -- S-1-5-21-508124448-3695470602-466989033-155771 

Magic URL:  http://magicweb02/magictsd 
",Jane Doe, Please verify (Jane Doe - 07/23/2012 0:00),verified (Jamie Doe -07/23/2012 00:00),,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655977 add security role xxxx,user updates,chore,accepted,7/19/2012 0:00,7/23/2012 0:00,,xxx,"Call Number: 655977 

My code looks like this:

try
{
    string file = File.ReadAllText("C:\\\\Users\\hacknj\\Desktop\\mo_daily_activity_20160627_1412.csv"); 

    // Define bad date                
    Regex badDate = new Regex(@"(\d{1,2}\/\d{1,2}\/\d{4})");

    // Find Matches
    MatchCollection matches = badDate.Matches(file);

    // Go through each match
    foreach (Match match in matches)
    {
        // get the match text
        string matchText = match.Groups[0].ToString();                    

        // Define DateTime
        DateTime parsedDate;

        DateTime.TryParse(matchText.Trim(), out parsedDate);

        file = file.Replace(matchText, parsedDate.ToString("MM/dd/yyyy"));                    
    }
    File.WriteAllText("C:\\\\Users\\hacknj\\Desktop\\TestFile.csv", file);
} 

Here's a little of what the dates look like once it's been written to file:

pad,pad,epic,,000009/26/2012 0:00,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
655656 add security role xxxx,user updates,chore,accepted,0000007/20/2012 0:00,00000007/23/2012 0:00,,xxxx,"Call Number: 655656 

If I look at the data right before it gets replaced it looks fine. I do this via

MessageBox.Show("Match Text: " + matchText.Trim() + "\nParsed Date: " + parsedDate.ToString("MM/dd/yyyy"));

Can someone tell me what I am doing that is causing these extra 0's to be generated when writing to the file?


Solution

  • The extra zeros are a result of this line running in a loop:

    file = file.Replace(matchText, parsedDate.ToString("MM/dd/yyyy"));
    

    If the same date appears more than once in the file, every time your regex finds one the above line replaces all of them. Therefore if the date required a leading zero, each time this line runs all the matching dates get a new leading zero.

    Instead, you can use Regex.Replace() with a MatchEvaluator function to reformat the matched dates:

    var newFile = Regex.Replace(file, @"(\d{1,2}\/\d{1,2}\/\d{4})", m =>
    {
        string matchText = m.Groups[0].ToString();
        DateTime parsedDate;
        if (DateTime.TryParse(matchText.Trim(), out parsedDate))
        {
            return parsedDate.ToString("MM/dd/yyyy");
        }
        else
        {
            return matchText;
        }
    });
    
    File.WriteAllText("C:\\\\Users\\hacknj\\Desktop\\TestFile.csv", newFile);