不带日期的日期排序

时间:2018-09-03 21:58:58

标签: c#

我有一个对象列表,这些对象具有名为date的字符串属性。这些对象是从SQL数据库填充的。 date属性包含MM-DD格式的对象的月和日(NO YEAR)。我希望能够以某种方式组织这些内容,以使下一个日期最接近当前日期的对象位于列表的顶部。

我之所以不使用MySQL中的DateTime对象或Date数据类型,是因为我试图防止在日期中每当日期过去时更新年份。我只希望能够查看日期是即将到来还是已经过去(显然,如果日期已经过去,它将接近列表的底部)。

我知道这种思维方式可能并不理想,并且可以接受其他建议。

编辑:

以下是有关我所使用的确切结构的更多信息:

示例数据库信息:

DomainName       RenewDate       ClientName

mydomain.com     02-01           John Doe
thisdomain.com   08-30           Tim Jones
thatdomain.com   10-10           Jane Smith

对象:

internal class Domain
{
    private string name;
    private string renewDate;
    private string client;

/* Getters, Setters, Constructors, & Other Methods */
}

一旦创建了对象,它们就会存储在列表中,我想根据最近的第二天对它们进行排序。例如,如果今天将其排序,则对象的顺序将为:

  • thatdomain.com | 10-10 |简·史密斯
  • mydomain.com | 02-01 |约翰·杜(John Doe)
  • thisdomain.com | 08-30 |蒂姆·琼斯

最后的重点是用此信息填充表格,以便我知道哪个域续订日期将要到来,因此我可以手动向客户发送发票。我认为没有必要添加年份,因为每次确切的日期过去时都必须更新它。

再次,我知道这可能不是解决此问题的最有效方法,并且愿意接受所有建议以实现更好的实施,这只是我目前的过程。

4 个答案:

答案 0 :(得分:1)

我想出了一些可以修改的代码。但是,这可以变得更通用(也可以更安全地进行生产)。

    class FancyDate
    {
        public int Month { get; set; }
        public int Day { get; set; }

        public FancyDate(string fancyDate)
        {
            var split = fancyDate.Split('-');
            Month = Int32.Parse(split[0]);
            Day = Int32.Parse(split[1]);
        }

        public override string ToString()
        {
            return $"{Month:D2}-{Day:D2}";
        }
    }

    class ClientRenewal
    {
        public string ClientName { get; set; }
        public FancyDate RenewalDate { get; set; } 
        public string DomainName { get; set; }

        public class ClientRenewalComparer : IComparer<ClientRenewal>
        {
            public int Compare(ClientRenewal x, ClientRenewal y)
            {
                if (x != null && y != null)
                    return String.Compare(x.RenewalDate.ToString(), y.RenewalDate.ToString(), StringComparison.Ordinal);
                throw new ArgumentNullException();
            }
        }

        public ClientRenewal(string clientName, string renewalDate, string domainName)
        {
            this.ClientName = clientName;
            this.RenewalDate = new FancyDate(renewalDate);
            this.DomainName = domainName;
        }

        public override string ToString()
        {
            return $"{DomainName} - {RenewalDate} - {ClientName}";
        }
    }
    class ClientRenewalList
    {
        private List<ClientRenewal> theClientList;

        public ClientRenewalList(List<ClientRenewal> list)
        {
            list.Sort(new ClientRenewal.ClientRenewalComparer());
            theClientList = new List<ClientRenewal>();
            foreach (var item in list)
            {
                theClientList.Add(item);
            }
        }

        private List<ClientRenewal> RotateListForCurrentDate()
        {
            // Bit of indirection to aid testing
            return RotateListForDate(DateTime.Now);
        }

        public List<ClientRenewal> RotateListForDate(DateTime dateTime)
        {
            var month = dateTime.Month;
            var day = dateTime.Day;
            int i = 0;
            while (i < theClientList.Count)
            {
                if (theClientList[i].RenewalDate.Month < month)
                {
                    i++;
                    continue;
                }
                if (theClientList[i].RenewalDate.Month == month)
                {
                    while (theClientList[i].RenewalDate.Day < day)
                    {
                        i++;
                    }
                }
                if (theClientList[i].RenewalDate.Month > month) break;
                if (theClientList[i].RenewalDate.Month >= month && theClientList[i].RenewalDate.Day >= day) break;
            }
            return theClientList.Skip(i).Concat(theClientList.Take(i)).ToList();
        }

        public List<ClientRenewal> GetListForDisplay()
        {
            return RotateListForCurrentDate();
        }
    }
    static void Main(string[] args)
    {

        //mydomain.com     02 - 01           John Doe
        //thisdomain.com   08 - 30           Tim Jones
        //thatdomain.com   10 - 10           Jane Smith
        var listOfClientRenewal = new List<ClientRenewal>()
        {
            new ClientRenewal("John Doe", "02-01", "mydomain.com"),
            new ClientRenewal("Tim Jones", "08-30", "thisdomain.com"),
            new ClientRenewal("Jane Smith", "10-10", "thatdomain.com")
        };
        var list = new ClientRenewalList(listOfClientRenewal).GetListForDisplay();
        foreach (var item in list)
        {
            Console.WriteLine(item);
        }
    }

这是输出:

Output

答案 1 :(得分:0)

如果您以字符串形式从数据库中读取它们,则可以尝试以下操作:

List<string> dates = GetDates(); //returns dates in form MM-DD from db
dates = dates.OrderBy(x=int.Parse(x.Split('-')[0])
.ThenBy(x=>int.Parse(x.Split('-')[1])
.ToList();

 List<string> oldDates = new List<string>();
 List<string> futureDates = new List<string>();
foreach(var date in dates)
{
    string[] splitDate = date.Split('-');
    int month = int.Parse(splitDate[0]);
    int day = int.Parse(splitDate[1]);
    if(month < DateTime.Today.Month)
       oldDates.Add(date);
    else if(month == DateTime.Today.Month)
    {
        if(day < DateTime.Today.Day)
            oldDates.Add(date);
        else
            futureDates.Add(date)(
    }
    else
        futureDates.Add(date);

     dates = futureDates.AddRange(oldDates);
}

我正在使用手机,所以请格式化:)

答案 2 :(得分:0)

您可以将这三个属性添加到您的类中,然后按顺序排序?

23:30:16.455 [vert.x-eventloop-thread-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxCapacityPerThread: 32768
23:30:16.455 [vert.x-eventloop-thread-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.maxSharedCapacityFactor: 2
23:30:16.455 [vert.x-eventloop-thread-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.linkCapacity: 16
23:30:16.455 [vert.x-eventloop-thread-1] DEBUG io.netty.util.Recycler - -Dio.netty.recycler.ratio: 8
23:30:16.478 [vert.x-eventloop-thread-1] DEBUG io.netty.buffer.AbstractByteBuf - -Dio.netty.buffer.bytebuf.checkAccessible: true
23:30:16.482 [vert.x-eventloop-thread-1] DEBUG io.netty.util.ResourceLeakDetectorFactory - Loaded default ResourceLeakDetector: io.netty.util.ResourceLeakDetector@51d486

您不在乎这一年,就像您说的那样。

希望这会有所帮助。

答案 3 :(得分:0)

如果我正确理解了您的要求,那么以下内容就足够了:

"." & vbCrLf

输出:

List<string> dates = new List<string>() { "02-01", "08-30", "10-10" };

CultureInfo ci = CultureInfo.InvariantCulture;
var sorted = dates.Select(s => DateTime.ParseExact(s, "MM-dd", ci))
                  .OrderBy(d => d);
var customSorted = sorted.SkipWhile(d => d <= DateTime.Today)
                         .Concat(sorted.TakeWhile(d => d <= DateTime.Today));

// In case you want them back as strings, otherwise, ignore the
// following line and add a `.ToList()` to the above line.
var customSortedStrings = customSorted.Select(d => d.ToString("MM-dd")).ToList();

foreach (string s in customSortedStrings)
    Console.WriteLine(s);