Search code examples
c#sortingdatetimeoffset

C# Sort / Order DateTimeOffset


Based on my answered question here(C# Sort / Order a textBox with given Values) I have another question. (Thanks to JohnG) I have now written my code to use with values the system gived to me. I don't now why, but the orderby-clause is completly ignored. The result with OrderBy and OrderByDescending is the same and nothing is sort / ordered.

Here the code which is created values by hand and working:

string[] test1 = { "2021-12-08", "2020-04-12", "2021-06-15", "2022-11-28", "2019-01-12" };
IEnumerable<string> query1 = test1.OrderBy(i => i.ToString());
foreach (string r in query1)
{
    textBox3.Text += r.ToString() + "\r\n";
}

Result:

2019-01-12
2020-04-12
2021-06-15
2021-12-08
2022-11-28

And here is the problem-code

var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_QuickFixEngineering");
var managementObjectCollection = searcher.Get();

foreach (ManagementObject queryObj in searcher.Get())
{
    string stringDate = queryObj["InstalledOn"].ToString();
    string format = "M/d/yyyy";
    CultureInfo provider = CultureInfo.InvariantCulture;
    DateTimeOffset result = new DateTimeOffset();
    result = DateTimeOffset.ParseExact(stringDate, format, provider, DateTimeStyles.AssumeUniversal);
    systemLastWindowsUpdate = result.ToString("yyyy-MM-dd");

    string[] test = { systemLastWindowsUpdate };
    IEnumerable<string> query = test.OrderByDescending(g => g.ToString());

    //MessageBox.Show(query.ToString()); // Gives System.Linq.OrderedEnumerable`2[System.String,System.String]
    foreach (string t in query)
    {
        textBox2.Text += t.ToString() + "\r\n";
    }
}

Result:

2021-07-19
2020-09-27
2020-09-27
2020-09-27
2021-03-01
2020-11-17
2020-11-17
2021-03-15
2020-12-14
2021-01-18
2021-07-19
2021-07-19

Hope anyone have an idea. I don't need a perfect and efficient code. I'm learning and it's absolutely OK with working code.


Solution

  • You are applying OrderByDescending to an array containing a single element string[] test = { systemLastWindowsUpdate };.

    Instead, append the formatted dates to a list and then sort the list. Sorting must be done after the foreach loop, i.e., after all the dates have been processed, to the entire list of dates:

    var searcher = new ManagementObjectSearcher(
        "SELECT * FROM Win32_QuickFixEngineering");
    var dates = new List<string>();
    foreach (ManagementObject queryObj in searcher.Get())
    {
        string stringDate = queryObj["InstalledOn"].ToString();
        string format = "M/d/yyyy";
        CultureInfo provider = CultureInfo.InvariantCulture;
        DateTimeOffset result = new DateTimeOffset();
        result = DateTimeOffset.ParseExact(
            stringDate, format, provider, DateTimeStyles.AssumeUniversal);
        systemLastWindowsUpdate = result.ToString("yyyy-MM-dd");
    
        dates.Add(systemLastWindowsUpdate);
    }
    
    // Now the list contains all the dates, and you can sort it:
    IEnumerable<string> query = dates.OrderByDescending(s => s);
    textBox2.Text = String.Join("\r\n", query);
    

    Also, do not append text repeatedly to a TextBox in a loop, because of the overhead involved. The TextBox might raise events each time, thus making the loop very slow. I use String.Join to create a string before assigning the final result to the TextBox once.


    You can also use the Language Integrated Query (LINQ) to do the conversion and sorting in one go with no loop and no list:

    var searcher = new ManagementObjectSearcher(
        "SELECT * FROM Win32_QuickFixEngineering");
    
    string format = "M/d/yyyy";
    CultureInfo provider = CultureInfo.InvariantCulture;
    
    var query = searcher.Get()
        .Select(queryObj => DateTimeOffset.ParseExact(
            queryObj["InstalledOn"].ToString(),
            format, provider, DateTimeStyles.AssumeUniversal
         ).ToString("yyyy-MM-dd"))
        .OrderByDescending(s => s);
    
    textBox2.Text = String.Join("\r\n", query);
    

    See also: Query Syntax and Method Syntax in LINQ (C#)