Compare version numbers without using split function

76,839

Solution 1

Can you use the Version class?
https://docs.microsoft.com/en-us/dotnet/api/system.version

It has an IComparable interface. Be aware this won't work with a 5-part version string like you've shown (is that really your version string?). Assuming your inputs are strings, here's a working sample with the normal .NET 4-part version string:

static class Program
{
    static void Main()
    {
        string v1 = "1.23.56.1487";
        string v2 = "1.24.55.487";

        var version1 = new Version(v1);
        var version2 = new Version(v2);

        var result = version1.CompareTo(version2);
        if (result > 0)
            Console.WriteLine("version1 is greater");
        else if (result < 0)
            Console.WriteLine("version2 is greater");
        else
            Console.WriteLine("versions are equal");
        return;

    }
}

Solution 2

If you can live with the major.minor.build.revision scheme you could use the .Net Version class. Otherwise you'd have to implement some kind of parsing from left to right and continuing until you have a difference or return that two versions are equal.

Solution 3

In addition to @JohnD 's answer there might be a need to compare only partial version numbers without using Split('.') or other string <-> int conversion bloat. I've just written an extension method CompareTo with 1 additional argument - number of significant parts of version number to compare (between 1 and 4).

public static class VersionExtensions
{
    public static int CompareTo(this Version version, Version otherVersion, int significantParts)
    {
        if(version == null)
        {
            throw new ArgumentNullException("version");
        }
        if(otherVersion == null)
        {
            return 1;
        }

        if(version.Major != otherVersion.Major && significantParts >= 1)
            if(version.Major > otherVersion.Major)
                return 1;
            else
                return -1;

        if(version.Minor != otherVersion.Minor && significantParts >= 2)
            if(version.Minor > otherVersion.Minor)
                return 1;
            else
                return -1;

        if(version.Build != otherVersion.Build && significantParts >= 3)
            if(version.Build > otherVersion.Build)
                return 1;
            else
                return -1;

        if(version.Revision != otherVersion.Revision && significantParts >= 4)
            if(version.Revision > otherVersion.Revision)
                return 1;
            else
                return -1;

        return 0; 
    }
}

Solution 4

public int compareVersion(string Version1,string Version2)
    {
        System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(@"([\d]+)");
        System.Text.RegularExpressions.MatchCollection m1 = regex.Matches(Version1);
        System.Text.RegularExpressions.MatchCollection m2 = regex.Matches(Version2);
        int min = Math.Min(m1.Count,m2.Count);
        for(int i=0; i<min;i++)
        {
            if(Convert.ToInt32(m1[i].Value)>Convert.ToInt32(m2[i].Value))
            {
                return 1;
            }
            if(Convert.ToInt32(m1[i].Value)<Convert.ToInt32(m2[i].Value))
            {
                return -1;
            }               
        }
        return 0;
    }

Solution 5

If for some reason you are not allowed to use the compare-method of the Version directly (e.g. in a client-server scenario), another approach is to extract a long number from the version and then compare the numbers with each other. However, the number needs to have the following format: Two digits for Major, Minor and Revision and four for Build.

How to extract the version number:

var version = Assembly.GetExecutingAssembly().GetName().Version;

long newVersion = version.Major * 1000000000L + 
                   version.Minor * 1000000L + 
                   version.Build * 1000L + 
                   version.Revision;

And then somewhere else you can just compare:

if(newVersion > installedVersion)
{
  //update code
}

Note: the installedVersion is a previously extracted long number

Share:
76,839
Sankar M
Author by

Sankar M

calm, composed, very cool, Focused, believe on my thoughts, crush on .NET and funny always :)

Updated on May 14, 2022

Comments

  • Sankar M
    Sankar M almost 2 years

    How do I compare version numbers?

    For instance:

    x = 1.23.56.1487.5

    y = 1.24.55.487.2

    • BoltClock
      BoltClock over 12 years
      What do you want the result to be?
    • psousa
      psousa over 12 years
      a version with 5 parts? If you were using the typical 4 part version you could use the System.Version class, which includes methods to compare versions and parse the version string
    • Gleno
      Gleno over 12 years
      What are the types of x and y?
    • Bob2Chiv
      Bob2Chiv over 12 years
      Whenever someone says "Don't use X, Y or Z", it always makes me wonder why. Why do you not want to use the split function? The split function seems like a good way to do this if you aren't going to use the System.Version class.
  • username
    username over 12 years
    Only if the version consists from 2-4 parts
  • Sankar M
    Sankar M over 12 years
    @dev_Boston only one exception...just do with these values v1=1.0001 and v2=1.1 .it gives me equal.
  • JohnD
    JohnD over 12 years
    Yes, the version strings are not decimal strings, and prepending zeroes to a portion of the version number is irrelevant. In other words, "00001" is equal to "1" in the 2nd part of the version string.
  • Ozgur Ozcitak
    Ozgur Ozcitak over 8 years
    Beware that this would return equals for compareVersion("1.3", "1.3.1")
  • Andrey Moiseev
    Andrey Moiseev over 7 years
    You can compare more readably as Version.Parse(v1) < Version.Parse(v2), because operator >(Version v1, Version v2) is implemented.
  • Stef Heyenrath
    Stef Heyenrath over 5 years
    To give all digits 3 places, the code should actually be : "version.Major * 1000000000L + version.Minor * 1000000L + version.Build * 1000L + version.Revision"
  • Fabian Bigler
    Fabian Bigler over 5 years
    @StefHeyenrath That is correct, feel free to adjust the above code to your own needs.
  • adospace
    adospace over 5 years
    Be aware that Version.Parse("6.0.0") is less than (<) Version.Parse("6.0.0.0") (i.e. are NOT equal). Debug.Assert(new Version("6.0.0") < new Version("6.0.0.0"));