【问题标题】:Create a unique number based on date and autoincremented number根据日期和自动递增编号创建唯一编号
【发布时间】:2015-08-28 04:24:30
【问题描述】:

我需要根据日期生成增量数字。 在前一个日期(比如 2014 年 1 月 6 日)创建的数字不应大于在即将到来的日期(比如 2014 年 1 月 8 日)创建的数字。 如何添加日期? 我试过了,但在少数情况下它失败了

static long num =1;
public long GetUniqueNumberAsPerDate(DateTime date)
{
    string dateStr = date.ToString("yyMMdd");
    long alwaysIncrementeduniqueNum = num + 1;

    return Convert.Int64(dateStr + alwaysIncrementeduniqueNum.ToString());
}

失败案例

通过日期:2014-06-06 人数 : 14 创建号码:14060614

通过日期:2013-06-06 号码 : 132 创建的数字:130606132(大于 14060614)

该函数可以被多个应用程序同时调用。所以日期时间(甚至毫秒)可以相同 这个问题的任何解决方案

【问题讨论】:

  • 我不明白。为什么不只检查您的date 是否小于08-Jan-2014
  • @SonerGönül:那个日期只是我的错误。编辑
  • 使用DateTime.Now.Ticks有什么问题?
  • 它可以生成重复值@Niklas
  • @Niklas:是的,dotctor 是对的

标签: c# .net uniqueidentifier


【解决方案1】:

问题似乎是您的运行编号(始终递增唯一编号)在 1 到 1000 的范围内变化。当您进行字符串连接时,最终编号的位数将更少或更多。

你可以做类似的事情

   const long k = 1000000;
   long value = long.Parse(dateStr) * k + alwaysIncrementeduniqueNum; 

假设您每天产生的记录不超过K,这应该可以保证您没有这个问题。

【讨论】:

  • 我不明白它是如何独一无二的?所以在同一天,会有很多次调用这个方法 GetUniqueNumberAsPerDate()。甚至毫秒也可以相同。所以数字不会是唯一的。如果我错了,请纠正
  • 糟糕:未完成 :) 您自己的示例是 130606132 与 14060614,问题与毫秒无关,但运行数字部分分别为 132 和 14。由于您使用字符串连接,这会产生分别为 9 位和 8 位数字。然后 2013 年的数字是最大的。使用我的方法,你会得到 130606000132 和 140606000014 测试可以。
  • 关键是你必须强制日期部分成为生成数字的最重要部分。
  • 我假设你会增加这个数字。它是指向正确方向的伪代码。您可能还应该使代码线程安全。
  • 一个更完整(但未经测试)的解决方案可能是gist.github.com/faester/6eef960ae990cc52c311
【解决方案2】:
    public long GetUniqueNumberAsPerDate(DateTime date)
    {
        double dateStr = date.ToOADate();
        dateStr *= 1000000;
        long alwaysIncrementeduniqueNum = num + 1;
        string uniqueNumber = alwaysIncrementeduniqueNum + " " + dateStr;

        return long.Parse(uniqueNumber);
    }

我认为这应该可行,它首先将日期转换为十进制数,然后将其乘以去除小数,然后将递增的数字作为字符串添加到前面。

您可以切换此区域(日期编号在前),以便日期编号在以后总是更大

【讨论】:

  • 它将如何独一无二?对于相同的 datestr(具有相同的毫秒数),它将返回重复的结果
  • 您不使用您的增量编号吗?每次调用此函数时都应增加 alwaysIncrementeduniqueNum
  • 正确,更快的建议相同的解决方案。向上 1
【解决方案3】:

我需要根据日期生成增量数字。在前一个日期创建的数字不应大于在未来日期创建的数字。

根据这个要求你可以简单地服用

date.Ticks

它提供了一个随DateTime 严格递增的数字。

如果你想避免在同一个刻度上出现相同的数字,你可以添加

Thread.Sleep(16);

Windows 的计时器中断以 64 Hz 的频率计时。 然而,这意味着您每秒生成的值不能超过 64 个。

【讨论】:

  • 会产生重复值
  • 是的,对于在完全相同的滴答声(20ms AFAIR)拍摄的两个日期,但他没有提到这是禁止的。
  • 如果你将它锁定在一个线程中并让它休眠一小段时间,它应该可以工作,对吧?
  • @Niklas:是的,它会起作用,但我想知道是否有任何其他解决方案可能。对我来说,我看起来像是一个逻辑问题
【解决方案4】:

如果你想在机器上增加数字,你可以使用这个类

public class IncrementalNumberGenerator
{
    private readonly string _path;
    private readonly EventWaitHandle _waitHandle; 

    public IncrementalNumberGenerator(string path)
    {
        _path = path;
        _waitHandle =  new EventWaitHandle(true, EventResetMode.AutoReset, Guid.NewGuid().ToString("N"));
        if (!File.Exists(_path))
            File.WriteAllText(_path,"0");
    }

    public ulong Next()
    {
        try
        {
            _waitHandle.WaitOne();
            var currentValue = ulong.Parse(File.ReadAllText(_path));
            File.WriteAllText(_path, (currentValue + 1).ToString());
            return currentValue + 1;
        }
        finally
        {
            _waitHandle.Set();
        }
    }
}

这将使用一个命名的等待句柄来同步不同的线程和进程。

像这样使用它

var ing = new IncrementalNumberGenerator(@"c:\data\temp\synch");

当您需要新号码时,请致电Next。通过使用此类,即使您有多个应用程序实例正在运行,或者即使您的应用程序重新启动,您也可以获得增量编号。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 2010-11-01
    相关资源
    最近更新 更多