মানচিত্রের সাথে নেট নেট টাইমস্প্যান সংরক্ষণ করার জন্য সঠিক এসকিউএল প্রকারটি কী?


196

আমি TimeSpanএসকিউএল সার্ভার 2008 আর 2 এ। নেট সংরক্ষণ করার চেষ্টা করছি ।

EF কোড ফার্স্ট মনে হচ্ছে এটি Time(7)এসকিউএল হিসাবে সংরক্ষণ করা উচিত ।

যাইহোক TimeSpan। নেট 24 ঘন্টা চেয়ে দীর্ঘ সময় ধরে পরিচালনা করতে পারে।

TimeSpanএসকিউএল সার্ভারে নেট । স্টোর পরিচালনা করার সর্বোত্তম উপায় কী ?


15
আমি এটি পুনরাবৃত্ত ইভেন্টগুলির দৈর্ঘ্য সঞ্চয় করতে ব্যবহার করছি। তাই আমি তারিখের চেয়ে পৃথক ইভেন্টের দৈর্ঘ্য ক্যাপচার করতে চেয়েছিলাম
গ্রিমিলার


1
সম্পর্কিত নকল নয়। আমি দুটোই লিখেছি। একটি হল কোড ফার্স্ট এবং টাইমস্প্যানের জন্য মানচিত্র কীভাবে পরিবর্তন করা যায় সে সম্পর্কে। অন্যটি আসল। নেট টাইমস্প্যান থেকে এসকিউএল ম্যাপিং সম্পর্কিত।
গ্রিমিলার

উত্তর:


222

আমি এটি ডাটাবেসে একটি হিসাবে BIGINTসঞ্চয় করে রাখতাম এবং আমি টিক্সের সংখ্যা সঞ্চয় করতাম (যেমন: টাইমস্প্যান.টিক্স সম্পত্তি)।

এইভাবে, আমি পুনরুদ্ধার করার সময় যদি টাইমস্প্যান অবজেক্টটি পেতে চাইতাম তবে আমি কেবল টাইমস্প্যানটি করতে পারি romফর্মটিক্স (মান) যা সহজ হবে।


3
আপনি কীভাবে স্ক্যুএলে গণনাগুলি পরিচালনা করবেন তা বলতে পারি যে এটির কত ঘন্টা রয়েছে তা গণনা করার জন্য আপনার দরকার ছিল?
পিটার

10
আমি সম্ভবত এই মত একটি সময় বস্তুর মধ্যে এঁটেল পোকা রূপান্তর চাই: SELECT CAST(DATEADD(MILLISECOND, @Ticks/CAST(10000 AS BIGINT), '1900-01-01') AS TIME)'1900-01-01'তারিখ না ব্যাপার, অবশ্যই, এটা ঠিক তৃতীয় দ্বারা প্রয়োজন পরিবর্তনশীল এর নেই DATEADD(...)ফাংশন। মনে রাখবেন একটি টিকটিতে 100 ন্যানোসেকেন্ড রয়েছে, তবে আপনি যদি ব্যবহার করেন তবে আপনি DATEADD(NANOSECOND...সম্ভবত একটি ওভারফ্লো পেতে পারেন, তাই মিলিসেকেন্ড ব্যবহার করে। এছাড়াও মনে রাখবেন যে আপনার TimeSpan.TicksPerMillisecondনিশ্চিত হয়ে সি # (10000 হওয়া উচিত) ব্যবহার করে এই সত্যটি পরীক্ষা করা উচিত।
টম চ্যান্টলার

একটি বিকল্প এটি স্ট্রিং হিসাবে সংরক্ষণ করে, আপনি এটি টাইমস্প্যান. পার্স (পাঠ্য) ব্যবহার করে লোড করতে পারেন। আকারের দৃষ্টিকোণ বা এসকিউএল কোয়েরি থেকে আদর্শ নয় তবে প্রয়োজনে টিএসকিউএলে পার্স করা যায়
ওয়াল্টার Vehoeven

65

পরামর্শের জন্য ধন্যবাদ. যেহেতু এসকিউএল সার্ভারে কোনও সমতুল্য নেই। আমি সহজভাবে একটি দ্বিতীয় ক্ষেত্র তৈরি করেছি যা টাইমস্প্যানকে টিক্সে রূপান্তরিত করে এবং এটি ডিবিতে সঞ্চিত করে। আমি তখন টাইমস্প্যান সংরক্ষণ করতে বাধা দিলাম

public Int64 ValidityPeriodTicks { get; set; }

[NotMapped]
public TimeSpan ValidityPeriod
{
    get { return TimeSpan.FromTicks(ValidityPeriodTicks); }
    set { ValidityPeriodTicks = value.Ticks; }
}

6
এছাড়াও ইএফ কোর ব্যবহারকারী যে কোনও ব্যক্তির জন্য - ২.১-এ আপনি ডাটাবেজে স্বচ্ছভাবে
টিক্সের টাইমস্প্যানগুলির

31

আপনার যদি 24 ঘণ্টার বেশি সঞ্চয় না করতে হয় তবে আপনি কেবল এসকিউএল সার্ভার ২০০৮ এবং পরে ম্যাপিংটি হ'ল সময় সঞ্চয় করতে পারেন

time (SQL Server) <-> TimeSpan(.NET)

আপনার যদি কেবল 24 ঘন্টা বা তারও কম স্টোর করতে হয় তবে কোনও রূপান্তর দরকার নেই।

সূত্র: http://msdn.microsoft.com/en-us/library/cc716729(v=vs.110).aspx

তবে , আপনি যদি 24 ঘন্টা-এর বেশি সঞ্চয় করতে চান তবে আপনাকে এটি টিক্সগুলিতে সঞ্চয় করতে হবে, ডেটা উদ্ধার করতে হবে এবং তারপরে টাইমস্প্যানে রূপান্তর করতে হবে। উদাহরণ স্বরূপ

int timeData = yourContext.yourTable.FirstOrDefault();
TimeSpan ts = TimeSpan.FromMilliseconds(timeData);

23
ওপি যেমন বলেছে, এসকিউএল সার্ভারে "সময়" ডেটা টাইপ কেবল 24 ঘন্টা পর্যন্ত সমর্থন করে, তিনি> 24 ঘন্টা
মিশেলজেড

11
এছাড়াও টাইমস্প্যান (.NET) নেতিবাচক হতে পারে যেখানে সময় (এসকিউএল সার্ভার) পারে না।
এডওয়ার্ড

11
একটি সময় এবং একটি সময়ের মধ্যে একটি প্রধান পার্থক্য আছে। সময়টি একটি নির্দিষ্ট দিনে সময়কে উপস্থাপন করে যেখানে সময়কাল দুটি মুহুর্তের মধ্যে পার্থক্য। এটি একটি অবস্থান (সময়) এবং দূরত্ব (সময়কাল) এর সাথে তুলনা করুন।
রামন ডি ক্লিন

3
Act একদম ঠিক। - এসকিউএল Timeটাইপটি কোনও সময়কাল উপস্থাপনের উদ্দেশ্যে নয়, তবে একটি ডেটটাইম মানটির সময় অংশ; এটি একটি ভয়ঙ্কর পছন্দ TimeSpan
ব্রেইনস্লাগস 83

19

সরাসরি সমতুল্য নেই isn't কেবল এটি সংখ্যায় সংরক্ষণ করুন, যেমন সেকেন্ডের সংখ্যা বা আপনার প্রয়োজনীয় নির্ভুলতার জন্য উপযুক্ত কিছু।


অর্থাত। এটিকে একটি ভাসা হিসাবে সংরক্ষণ করুন এবং d টাইমস্প্যান.ফ্রমসেকেন্ডস ms এমএসডিএন.মাইক্রোসফটকম
সিএডি

7

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে আমি নিশ্চিত করতে চেয়েছিলাম যে কয়েকটি বিকল্পের উল্লেখ আছে।

যেহেতু আপনি একটি সময় স্কুয়েল ডেটাটাইপ ক্ষেত্রে 24 ঘন্টাের বেশি টাইমস্প্যান সংরক্ষণ করতে পারবেন না; অন্য কয়েকটি বিকল্প হতে পারে।

  1. টাইমস্প্যানের টোস্ট্রিং সঞ্চয় করতে একটি বার্চার (xx) ব্যবহার করুন। এর সুবিধাটি হ'ল যথার্থতাটি ডেটাটাইপ বা গণনাতে বেক করা উচিত নয়, (সেকেন্ড বনাম মিলিসেকেন্ড বনাম কয়েক দিন বনাম পঞ্চাশ রাত) আপনাকে যা করতে হবে তা দরকার টাইমস্প্যান.পার্স / ট্রাইপার্স use এই আমি কি করতে হবে।

  2. দ্বিতীয় তারিখ, তারিখ সময় বা ডেটটাইমসেট ব্যবহার করুন, যা প্রথম তারিখ + টাইমস্পানের ফলাফল সঞ্চয় করে। ডিবি থেকে পড়া টাইমস্প্যান x = দ্বিতীয় তারিখ - প্রথম তারিখের বিষয় matter এই বিকল্পটি ব্যবহার করা আপনাকে অন্যান্য নন। নেট ডেটা অ্যাক্সেস লাইব্রেরিগুলির জন্য একই ডেটা অ্যাক্সেস করতে পারে তবে টাইমস্প্যানগুলি বুঝতে না পারে; যদি আপনার এমন পরিবেশ থাকে।


1
বিকল্প 2 এর মতো শোনা যাচ্ছে যে এটি এখন এবং পরে কার্যকর হতে পারে। thx
রিক্স

3

একটি সময়কাল (সম্ভবত 2 বার বা তারিখের সময়ের পার্থক্য গণনা করা) সম্ভবত সবচেয়ে উত্স উত্স সঙ্গে সামঞ্জস্য রাখতে, আপনি TimeSpanএকটি এসকিউএল সার্ভারের DateTimeধরণ হিসাবে একটি .NET সংরক্ষণ করতে পারেন ।

এর কারণ SQL সার্ভার, 2 পার্থক্য মধ্যে DateTime'(গুলি Castকরার Float' র এবং তারপর Castএকটি ফিরে DateTime) কেবল একটি হলDateTime জানুয়ারি 1, 1900 প্রাক্তন আপেক্ষিক। +0.1 সেকেন্ডের পার্থক্য 1 জানুয়ারী, 1900 00: 00: 00.100 এবং -0.1 সেকেন্ড হবে 31 ডিসেম্বর, 1899 23: 59: 59.900।

.NET TimeSpanকে একটি এসকিউএল সার্ভারের ধরণে রূপান্তর করতে DateTime, আপনি প্রথমে এটি 1 জানুয়ারী, 1900-এ DateTimeযোগ করে একটি। নেট টাইপে রূপান্তর করতে পারেন DateTimeOf অবশ্যই যখন আপনি এসকিউএল সার্ভার থেকে এটি নেট এ পড়েন, আপনি প্রথমে এটি একটি .NET এ পড়ুন DateTimeএবং তারপরে এটি NET এ রূপান্তর করতে এটি থেকে 1 জানুয়ারী 1900 কে বিয়োগ করুন TimeSpan

এসকিউএল সার্ভারের DateTimeএবং এসকিউএল সার্ভারের মধ্যে (যেমন টি-এসকিউএল মাধ্যমে) এবং এসকিউএল সার্ভারের মধ্যে সময়কাল বিস্তৃত হয়েছে এমন ব্যবহারের ক্ষেত্রে এবং আপনার সীমা এবং যথাযথ প্রয়োজনের উপর নির্ভর করে, এগুলি সংরক্ষণ করা ব্যবহারিক নাও হতে পারে মিলিসেকেন্ড হিসাবে (উল্লেখ করার মতো নয় Ticks) কারণ Intটাইপটি ফিরে এসেছে DateDiff(বনাম। BigIntএসএস 2016+ এর থেকে DateDiff_Big) ~ 24 দিনের মূল্য মিলি সেকেন্ড এবং ~ 67 ইয়ার পরে প্রবাহিত হয়। সেকেন্ডের তবে, এই সমাধানটি 0.1 সেকেন্ডে নিচে এবং -১77 থেকে +৮,০৯৯ বছর অবধি যথাযথতার সাথে সময়সীমা পরিচালনা করবে ..

সতর্কবাণী:

  1. এটি কেবল তখনই কাজ করবে যদি 1 জানুয়ারী 1900 এর সাথে সম্পর্কিত পার্থক্যের ফলে কোনও এসকিউএল সার্ভার DateTimeপ্রকারের (11 জানুয়ারী 1, 1753 থেকে 31 ডিসেম্বর, 9999 ওরফে -147 থেকে +8,099 বছর) এর মধ্যে একটি মান হবে । NET TimeSpanপাশের দিকে আমাদের খুব বেশি উদ্বিগ্ন হওয়ার দরকার নেই, যেহেতু এটি k 29 কে থেকে + 29 কেয়ার ধরে রাখতে পারে। আমি এসকিউএল সার্ভারের DateTime2প্রকারের উল্লেখ করিনি (যার পরিধি, নেতিবাচক দিক থেকে এসকিউএল সার্ভারের চেয়ে অনেক বেশি বেশি DateTime), কারণ: ক) এটি একটি সরল Castএবং খ এর মাধ্যমে সংখ্যায় রূপান্তরিত করা যায় না ) DateTimeএর পরিসরটি যথেষ্ট হবে ব্যবহারের ক্ষেত্রে বিস্তৃত ক্ষেত্রে।

  2. এসকিউএল সার্ভারের DateTimeপার্থক্যগুলি Cast- থেকে - Floatএবং - ব্যাক পদ্ধতিটি 0.1 সেকেন্ডের বাইরে সঠিক বলে মনে হয় না।


আমি ভুলে গিয়েছি এমনকি আমি এই কিউটিও খুব কম পড়তে পারি যে আমি এই এ লিখেছি এবং আবার একটি এ অনুসন্ধান করেছিলাম। আমি এইটি পড়তে শুরু করেছিলাম এবং নিজেকে ভেবেছিলাম: (বাহ, এটি এখন পর্যন্ত সেরা উত্তর!)। : ডি
টম

3

ডাটাবেসে একটি টাইমস্প্যান উপস্থাপনের একাধিক উপায় রয়েছে।

সময়

এই ডাটাটাইপ এসকিউএল সার্ভার 2008 সাল থেকে সমর্থিত এবং হয় prefered উপায় একটি সঞ্চয় করতে TimeSpan। কোনও ম্যাপিংয়ের দরকার নেই। এটি এসকিউএল কোডের সাথেও ভাল কাজ করে।

public TimeSpan ValidityPeriod { get; set; }

তবে, আসল প্রশ্নে বর্ণিত হিসাবে, এই ডেটাটাইপটি 24 ঘন্টা সীমাবদ্ধ।

datetimeoffset

datetimeoffsetডাটাটাইপ সরাসরি মানচিত্র System.DateTimeOffset। এটি datetime/ datetime2থেকে ইউটিসির মধ্যে অফসেটটি প্রকাশ করতে ব্যবহৃত হয় তবে আপনি এটি ব্যবহার করতে পারেন TimeSpan

তবে, যেহেতু ডেটাটাইপটি একটি খুব নির্দিষ্ট শব্দার্থক পরামর্শ দেয় তাই আপনার অন্যান্য বিকল্পগুলিও বিবেচনা করা উচিত।

ডেটটাইম / ডেটটাইম 2

একটি পদ্ধতির ব্যবহার datetimeবা datetime2প্রকারগুলি হতে পারে । এটি এমন পরিস্থিতিতে সবচেয়ে ভাল যেখানে আপনার সরাসরি ডাটাবেসটিতে মানগুলি প্রক্রিয়া করা প্রয়োজন ie দর্শন, সঞ্চিত পদ্ধতি, বা রিপোর্টের জন্য। ত্রুটিটি হ'ল DateTime(1900,01,01,00,00,00)আপনার ব্যবসায়ের যুক্তিতে টাইমস্প্যানটি ফিরে পেতে আপনাকে তারিখ থেকে মানটি বিয়োগ করতে হবে।

public DateTime ValidityPeriod { get; set; }

[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
    get { return ValidityPeriod - DateTime(1900,01,01,00,00,00); }
    set { ValidityPeriod = DateTime(1900,01,01,00,00,00) + value; }
}

bigint

টাইমস্প্যানকে টিক্সে রূপান্তর করা এবং bigintডেটাটাইপ ব্যবহার করা অন্য পদ্ধতি হতে পারে । তবে এসকিউএল কোয়েরিতে এই পদ্ধতির একটি অসুবিধা রয়েছে যা এটি ব্যবহার করা জটিল।

public long ValidityPeriod { get; set; }

[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
    get { return TimeSpan.FromTicks(ValidityPeriod); }
    set { ValidityPeriod = value.Ticks; }
}

varchar (এন)

এটি সেই ক্ষেত্রে সবচেয়ে ভাল যেখানে মান দ্বারা মানযোগ্য হওয়া উচিত। আপনি এই ফর্ম্যাটটি এসকিউএল কোয়েরিতে CONVERT(datetime, ValidityPeriod)ফাংশনটি ব্যবহার করে ব্যবহার করতে পারেন । প্রয়োজনীয় নির্ভুলতার উপর নির্ভরশীল, আপনার 8 থেকে 25 টি অক্ষরের প্রয়োজন হবে।

public string ValidityPeriod { get; set; }

[NotMapped]
public TimeSpan ValidityPeriodTimeSpan
{
    get { return TimeSpan.Parse(ValidityPeriod); }
    set { ValidityPeriod = value.ToString("HH:mm:ss"); }
}

বোনাস: সময়কাল এবং সময়কাল

একটি স্ট্রিং ব্যবহার করে আপনি নোডটাইম ডেটাটাইপগুলি বিশেষত Durationএবং Period। প্রথমটি মূলত টাইমস্প্যানের সমান, তবে পরবর্তীতে শ্রদ্ধা হয় যে কিছু দিন এবং মাস অন্যদের চেয়ে দীর্ঘ বা সংক্ষিপ্ত হয় (যেমন জানুয়ারীর ৩১ দিন থাকে এবং ফেব্রুয়ারিতে ২৮ বা ২৯ থাকে; দিবালোক সাশ্রয়ের সময় কিছু দিন বেশি বা সংক্ষিপ্ত থাকে) )। এই জাতীয় ক্ষেত্রে, টাইমস্প্যান ব্যবহার করা ভুল পছন্দ।

পিরিয়ডস রূপান্তর করতে আপনি এই কোডটি ব্যবহার করতে পারেন:

using NodaTime;
using NodaTime.Serialization.JsonNet;

internal static class PeriodExtensions
{
    public static Period ToPeriod(this string input)
    {
        var js = JsonSerializer.Create(new JsonSerializerSettings());
        js.ConfigureForNodaTime(DateTimeZoneProviders.Tzdb);
        var quoted = string.Concat(@"""", input, @"""");
        return js.Deserialize<Period>(new JsonTextReader(new StringReader(quoted)));
    }
}

এবং তারপরে এটি ব্যবহার করুন

public string ValidityPeriod { get; set; }

[NotMapped]
public Period ValidityPeriodPeriod
{
    get => ValidityPeriod.ToPeriod();
    set => ValidityPeriod = value.ToString();
}

আমি সত্যিই পছন্দ করি NodaTimeএবং এটি প্রায়শই আমাকে জটিল বাগ এবং প্রচুর মাথা ব্যাথার হাত থেকে বাঁচায়। এখানে অপূর্ণতা হ'ল আপনি এটি সত্যিই এসকিউএল কোয়েরিতে ব্যবহার করতে পারবেন না এবং মেমরির জন্য গণনা করা দরকার।

সিএলআর ব্যবহারকারী-সংজ্ঞায়িত প্রকার

আপনার কাছে কাস্টম ডেটাটাইপ ব্যবহার এবং TimeSpanসরাসরি একটি কাস্টম ক্লাস সমর্থন করার বিকল্প রয়েছে । বিস্তারিত জানতে সিএলআর ব্যবহারকারী-সংজ্ঞায়িত প্রকারগুলি দেখুন।

এখানে অপূর্ণতা হ'ল ডেটাটাইপ এসকিউএল রিপোর্টগুলির সাথে ভাল আচরণ করতে পারে না। এছাড়াও, এসকিউএল সার্ভারের কয়েকটি সংস্করণ (অ্যাজুরে, লিনাক্স, ডেটা ওয়্যারহাউস) সমর্থিত নয়।

মান রূপান্তর

সত্তা ফ্রেমওয়ার্ক কোর 2.1 দিয়ে শুরু করে, আপনার কাছে মান রূপান্তরগুলি ব্যবহার করার বিকল্প রয়েছে ।

যাইহোক, এটি ব্যবহার করার সময়, ইএফ অনেকগুলি প্রশ্নের এসকিউএলে রূপান্তর করতে সক্ষম হবে না , এর ফলে মেমোরিগুলিতে ক্যোয়ারী চালিত হবে; আপনার অ্যাপ্লিকেশনটিতে সম্ভাব্য প্রচুর এবং প্রচুর ডেটা স্থানান্তর করা।

কমপক্ষে আপাতত এটি ব্যবহার না করাই ভাল হতে পারে এবং কেবল অটোমেপারের সাথে ক্যোয়ারির ফলাফল ম্যাপ করুন ।


1

সাধারণত, আমি টাইমস্প্যান থেকে টিক্স সহ জনসংখ্যার হিসাবে একটি টাইমস্প্যান সংরক্ষণ করি previously আপনি টাইমস্প্যান.টোস্ট্রিং () এর আউটপুট দিয়ে পপুলেটে একটি বারচর (26) হিসাবে একটি টাইমস্প্যান সংরক্ষণ করতে পারেন। আমি যে চারটি স্কেলার ফাংশন লিখেছি (কনভার্টফ্রোমটাইমস্প্যানস্ট্রিং, কনভার্ট টোটাইমস্প্যান স্ট্রিং, ডেটএডডটিক্স, ডেটডিফটিক্স) এসকিউএল দিকের টাইমস্প্যান পরিচালনা করার জন্য এবং হ্যাকগুলি এড়ানোর জন্য সহায়ক যা কৃত্রিমভাবে বেঁধে রেঞ্জ তৈরি করে। যদি আপনি কোনও। নেট টাইমস্প্যানের মধ্যে অন্তর সংরক্ষণ করতে পারেন তবে এই ফাংশনগুলির সাথে এটিও কাজ করা উচিত। অতিরিক্তভাবে, ফাংশনগুলি আপনাকে .NET ফ্রেমওয়ার্ক অন্তর্ভুক্ত না এমন প্রযুক্তি ব্যবহার করে এমনকি টাইমস্প্যানস এবং 100-ন্যানোসেকেন্ড টিক্সের সাথে কাজ করার অনুমতি দেয়।

DROP FUNCTION [dbo].[DateDiffTicks]
GO

DROP FUNCTION [dbo].[DateAddTicks]
GO

DROP FUNCTION [dbo].[ConvertToTimeSpanString]
GO

DROP FUNCTION [dbo].[ConvertFromTimeSpanString]
GO

SET ANSI_NULLS OFF
GO

SET QUOTED_IDENTIFIER OFF
GO

-- =============================================
-- Author:      James Coe
-- Create date: 2011-05-23
-- Description: Converts from a varchar(26) TimeSpan string to a bigint containing the number of 100 nanosecond ticks.
-- =============================================
/*
    [-][d.]hh:mm:ss[.fffffff] 

    "-" 
     A minus sign, which indicates a negative time interval. No sign is included for a positive time span.

    "d" 
     The number of days in the time interval. This element is omitted if the time interval is less than one day. 

    "hh" 
     The number of hours in the time interval, ranging from 0 to 23. 

    "mm" 
     The number of minutes in the time interval, ranging from 0 to 59. 

    "ss" 
     The number of seconds in the time interval, ranging from 0 to 59. 

    "fffffff" 
     Fractional seconds in the time interval. This element is omitted if the time interval does not include 
     fractional seconds. If present, fractional seconds are always expressed using seven decimal digits.
    */
CREATE FUNCTION [dbo].[ConvertFromTimeSpanString] (@timeSpan varchar(26))
RETURNS bigint
AS
BEGIN
    DECLARE @hourStart int
    DECLARE @minuteStart int
    DECLARE @secondStart int
    DECLARE @ticks bigint
    DECLARE @hours bigint
    DECLARE @minutes bigint
    DECLARE @seconds DECIMAL(9, 7)

    SET @hourStart = CHARINDEX('.', @timeSpan) + 1
    SET @minuteStart = CHARINDEX(':', @timeSpan) + 1
    SET @secondStart = CHARINDEX(':', @timespan, @minuteStart) + 1
    SET @ticks = 0

    IF (@hourStart > 1 AND @hourStart < @minuteStart)
    BEGIN
        SET @ticks = CONVERT(bigint, LEFT(@timespan, @hourstart - 2)) * 864000000000
    END
    ELSE
    BEGIN
        SET @hourStart = 1
    END

    SET @hours = CONVERT(bigint, SUBSTRING(@timespan, @hourStart, @minuteStart - @hourStart - 1))
    SET @minutes = CONVERT(bigint, SUBSTRING(@timespan, @minuteStart, @secondStart - @minuteStart - 1))
    SET @seconds = CONVERT(DECIMAL(9, 7), SUBSTRING(@timespan, @secondStart, LEN(@timeSpan) - @secondStart + 1))

    IF (@ticks < 0)
    BEGIN
        SET @ticks = @ticks - @hours * 36000000000
    END
    ELSE
    BEGIN
        SET @ticks = @ticks + @hours * 36000000000
    END

    IF (@ticks < 0)
    BEGIN
        SET @ticks = @ticks - @minutes * 600000000
    END
    ELSE
    BEGIN
        SET @ticks = @ticks + @minutes * 600000000
    END

    IF (@ticks < 0)
    BEGIN
        SET @ticks = @ticks - @seconds * 10000000.0
    END
    ELSE
    BEGIN
        SET @ticks = @ticks + @seconds * 10000000.0
    END

    RETURN @ticks
END
GO

-- =============================================
-- Author:      James Coe
-- Create date: 2011-05-23
-- Description: Converts from a bigint containing the number of 100 nanosecond ticks to a varchar(26) TimeSpan string.
-- =============================================
/*
[-][d.]hh:mm:ss[.fffffff] 

"-" 
 A minus sign, which indicates a negative time interval. No sign is included for a positive time span.

"d" 
 The number of days in the time interval. This element is omitted if the time interval is less than one day. 

"hh" 
 The number of hours in the time interval, ranging from 0 to 23. 

"mm" 
 The number of minutes in the time interval, ranging from 0 to 59. 

"ss" 
 The number of seconds in the time interval, ranging from 0 to 59. 

"fffffff" 
 Fractional seconds in the time interval. This element is omitted if the time interval does not include 
 fractional seconds. If present, fractional seconds are always expressed using seven decimal digits.
*/
CREATE FUNCTION [dbo].[ConvertToTimeSpanString] (@ticks bigint)
RETURNS varchar(26)
AS
BEGIN
    DECLARE @timeSpanString varchar(26)

    IF (@ticks < 0)
    BEGIN
        SET @timeSpanString = '-'
    END
    ELSE
    BEGIN
        SET @timeSpanString = ''
    END

    -- Days
    DECLARE @days bigint

    SET @days = FLOOR(ABS(@ticks / 864000000000.0))

    IF (@days > 0)
    BEGIN
        SET @timeSpanString = @timeSpanString + CONVERT(varchar(26), @days) + '.'
    END

    SET @ticks = ABS(@ticks % 864000000000)
    -- Hours
    SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 36000000000.0)), 2) + ':'
    SET @ticks = @ticks % 36000000000
    -- Minutes
    SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 600000000.0)), 2) + ':'
    SET @ticks = @ticks % 600000000
    -- Seconds
    SET @timeSpanString = @timeSpanString + RIGHT('0' + CONVERT(varchar(26), FLOOR(@ticks / 10000000.0)), 2)
    SET @ticks = @ticks % 10000000

    -- Fractional Seconds
    IF (@ticks > 0)
    BEGIN
        SET @timeSpanString = @timeSpanString + '.' + LEFT(CONVERT(varchar(26), @ticks) + '0000000', 7)
    END

    RETURN @timeSpanString
END
GO

-- =============================================
-- Author:      James Coe
-- Create date: 2011-05-23
-- Description: Adds the specified number of 100 nanosecond ticks to a date.
-- =============================================
CREATE FUNCTION [dbo].[DateAddTicks] (
    @ticks bigint
    , @starting_date datetimeoffset
    )
RETURNS datetimeoffset
AS
BEGIN
    DECLARE @dateTimeResult datetimeoffset

    IF (@ticks < 0)
    BEGIN
        -- Hours
        SET @dateTimeResult = DATEADD(HOUR, CEILING(@ticks / 36000000000.0), @starting_date)
        SET @ticks = @ticks % 36000000000
        -- Seconds
        SET @dateTimeResult = DATEADD(SECOND, CEILING(@ticks / 10000000.0), @dateTimeResult)
        SET @ticks = @ticks % 10000000
        -- Nanoseconds
        SET @dateTimeResult = DATEADD(NANOSECOND, @ticks * 100, @dateTimeResult)
    END
    ELSE
    BEGIN
        -- Hours
        SET @dateTimeResult = DATEADD(HOUR, FLOOR(@ticks / 36000000000.0), @starting_date)
        SET @ticks = @ticks % 36000000000
        -- Seconds
        SET @dateTimeResult = DATEADD(SECOND, FLOOR(@ticks / 10000000.0), @dateTimeResult)
        SET @ticks = @ticks % 10000000
        -- Nanoseconds
        SET @dateTimeResult = DATEADD(NANOSECOND, @ticks * 100, @dateTimeResult)
    END

    RETURN @dateTimeResult
END
GO

-- =============================================
-- Author:      James Coe
-- Create date: 2011-05-23
-- Description:  Gets the difference between two dates in 100 nanosecond ticks.
-- =============================================
CREATE FUNCTION [dbo].[DateDiffTicks] (
    @starting_date datetimeoffset
    , @ending_date datetimeoffset
    )
RETURNS bigint
AS
BEGIN
    DECLARE @ticks bigint
    DECLARE @days bigint
    DECLARE @hours bigint
    DECLARE @minutes bigint
    DECLARE @seconds bigint

    SET @hours = DATEDIFF(HOUR, @starting_date, @ending_date)
    SET @starting_date = DATEADD(HOUR, @hours, @starting_date)
    SET @ticks = @hours * 36000000000
    SET @seconds = DATEDIFF(SECOND, @starting_date, @ending_date)
    SET @starting_date = DATEADD(SECOND, @seconds, @starting_date)
    SET @ticks = @ticks + @seconds * 10000000
    SET @ticks = @ticks + CONVERT(bigint, DATEDIFF(NANOSECOND, @starting_date, @ending_date)) / 100

    RETURN @ticks
END
GO

--- BEGIN Test Harness ---
SET NOCOUNT ON

DECLARE @dateTimeOffsetMinValue datetimeoffset
DECLARE @dateTimeOffsetMaxValue datetimeoffset
DECLARE @timeSpanMinValueString varchar(26)
DECLARE @timeSpanZeroString varchar(26)
DECLARE @timeSpanMaxValueString varchar(26)
DECLARE @timeSpanMinValueTicks bigint
DECLARE @timeSpanZeroTicks bigint
DECLARE @timeSpanMaxValueTicks bigint
DECLARE @dateTimeOffsetMinMaxDiffTicks bigint
DECLARE @dateTimeOffsetMaxMinDiffTicks bigint

SET @dateTimeOffsetMinValue = '0001-01-01T00:00:00.0000000+00:00'
SET @dateTimeOffsetMaxValue = '9999-12-31T23:59:59.9999999+00:00'
SET @timeSpanMinValueString = '-10675199.02:48:05.4775808'
SET @timeSpanZeroString = '00:00:00'
SET @timeSpanMaxValueString = '10675199.02:48:05.4775807'
SET @timeSpanMinValueTicks = -9223372036854775808
SET @timeSpanZeroTicks = 0
SET @timeSpanMaxValueTicks = 9223372036854775807
SET @dateTimeOffsetMinMaxDiffTicks = 3155378975999999999
SET @dateTimeOffsetMaxMinDiffTicks = -3155378975999999999

-- TimeSpan Conversion Tests
PRINT 'Testing TimeSpan conversions...'

DECLARE @convertToTimeSpanStringMinTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringMinTimeSpanResult bigint
DECLARE @convertToTimeSpanStringZeroTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringZeroTimeSpanResult bigint
DECLARE @convertToTimeSpanStringMaxTicksResult varchar(26)
DECLARE @convertFromTimeSpanStringMaxTimeSpanResult bigint

SET @convertToTimeSpanStringMinTicksResult = dbo.ConvertToTimeSpanString(@timeSpanMinValueTicks)
SET @convertFromTimeSpanStringMinTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanMinValueString)
SET @convertToTimeSpanStringZeroTicksResult = dbo.ConvertToTimeSpanString(@timeSpanZeroTicks)
SET @convertFromTimeSpanStringZeroTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanZeroString)
SET @convertToTimeSpanStringMaxTicksResult = dbo.ConvertToTimeSpanString(@timeSpanMaxValueTicks)
SET @convertFromTimeSpanStringMaxTimeSpanResult = dbo.ConvertFromTimeSpanString(@timeSpanMaxValueString)

-- Test Results
SELECT 'Convert to TimeSpan String from Ticks (Minimum)' AS Test
    , CASE 
        WHEN @convertToTimeSpanStringMinTicksResult = @timeSpanMinValueString
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @timeSpanMinValueTicks AS [Ticks]
    , CONVERT(varchar(26), NULL) AS [TimeSpan String]
    , CONVERT(varchar(26), @convertToTimeSpanStringMinTicksResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanMinValueString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Minimum)' AS Test
    , CASE 
        WHEN @convertFromTimeSpanStringMinTimeSpanResult = @timeSpanMinValueTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , NULL AS [Ticks]
    , @timeSpanMinValueString AS [TimeSpan String]
    , CONVERT(varchar(26), @convertFromTimeSpanStringMinTimeSpanResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanMinValueTicks) AS [Expected Result]
UNION ALL
SELECT 'Convert to TimeSpan String from Ticks (Zero)' AS Test
    , CASE 
        WHEN @convertToTimeSpanStringZeroTicksResult = @timeSpanZeroString
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @timeSpanZeroTicks AS [Ticks]
    , CONVERT(varchar(26), NULL) AS [TimeSpan String]
    , CONVERT(varchar(26), @convertToTimeSpanStringZeroTicksResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanZeroString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Zero)' AS Test
    , CASE 
        WHEN @convertFromTimeSpanStringZeroTimeSpanResult = @timeSpanZeroTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , NULL AS [Ticks]
    , @timeSpanZeroString AS [TimeSpan String]
    , CONVERT(varchar(26), @convertFromTimeSpanStringZeroTimeSpanResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanZeroTicks) AS [Expected Result]
UNION ALL
SELECT 'Convert to TimeSpan String from Ticks (Maximum)' AS Test
    , CASE 
        WHEN @convertToTimeSpanStringMaxTicksResult = @timeSpanMaxValueString
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @timeSpanMaxValueTicks AS [Ticks]
    , CONVERT(varchar(26), NULL) AS [TimeSpan String]
    , CONVERT(varchar(26), @convertToTimeSpanStringMaxTicksResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanMaxValueString) AS [Expected Result]
UNION ALL
SELECT 'Convert from TimeSpan String to Ticks (Maximum)' AS Test
    , CASE 
        WHEN @convertFromTimeSpanStringMaxTimeSpanResult = @timeSpanMaxValueTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , NULL AS [Ticks]
    , @timeSpanMaxValueString AS [TimeSpan String]
    , CONVERT(varchar(26), @convertFromTimeSpanStringMaxTimeSpanResult) AS [Actual Result]
    , CONVERT(varchar(26), @timeSpanMaxValueTicks) AS [Expected Result]

-- Ticks Date Add Test
PRINT 'Testing DateAddTicks...'

DECLARE @DateAddTicksPositiveTicksResult datetimeoffset
DECLARE @DateAddTicksZeroTicksResult datetimeoffset
DECLARE @DateAddTicksNegativeTicksResult datetimeoffset

SET @DateAddTicksPositiveTicksResult = dbo.DateAddTicks(@dateTimeOffsetMinMaxDiffTicks, @dateTimeOffsetMinValue)
SET @DateAddTicksZeroTicksResult = dbo.DateAddTicks(@timeSpanZeroTicks, @dateTimeOffsetMinValue)
SET @DateAddTicksNegativeTicksResult = dbo.DateAddTicks(@dateTimeOffsetMaxMinDiffTicks, @dateTimeOffsetMaxValue)

-- Test Results
SELECT 'Date Add with Ticks Test (Positive)' AS Test
    , CASE 
        WHEN @DateAddTicksPositiveTicksResult = @dateTimeOffsetMaxValue
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @dateTimeOffsetMinMaxDiffTicks AS [Ticks]
    , @dateTimeOffsetMinValue AS [Starting Date]
    , @DateAddTicksPositiveTicksResult AS [Actual Result]
    , @dateTimeOffsetMaxValue AS [Expected Result]
UNION ALL
SELECT 'Date Add with Ticks Test (Zero)' AS Test
    , CASE 
        WHEN @DateAddTicksZeroTicksResult = @dateTimeOffsetMinValue
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @timeSpanZeroTicks AS [Ticks]
    , @dateTimeOffsetMinValue AS [Starting Date]
    , @DateAddTicksZeroTicksResult AS [Actual Result]
    , @dateTimeOffsetMinValue AS [Expected Result]
UNION ALL
SELECT 'Date Add with Ticks Test (Negative)' AS Test
    , CASE 
        WHEN @DateAddTicksNegativeTicksResult = @dateTimeOffsetMinValue
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @dateTimeOffsetMaxMinDiffTicks AS [Ticks]
    , @dateTimeOffsetMaxValue AS [Starting Date]
    , @DateAddTicksNegativeTicksResult AS [Actual Result]
    , @dateTimeOffsetMinValue AS [Expected Result]

-- Ticks Date Diff Test
PRINT 'Testing Date Diff Ticks...'

DECLARE @dateDiffTicksMinMaxResult bigint
DECLARE @dateDiffTicksMaxMinResult bigint

SET @dateDiffTicksMinMaxResult = dbo.DateDiffTicks(@dateTimeOffsetMinValue, @dateTimeOffsetMaxValue)
SET @dateDiffTicksMaxMinResult = dbo.DateDiffTicks(@dateTimeOffsetMaxValue, @dateTimeOffsetMinValue)

-- Test Results
SELECT 'Date Difference in Ticks Test (Min, Max)' AS Test
    , CASE 
        WHEN @dateDiffTicksMinMaxResult = @dateTimeOffsetMinMaxDiffTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @dateTimeOffsetMinValue AS [Starting Date]
    , @dateTimeOffsetMaxValue AS [Ending Date]
    , @dateDiffTicksMinMaxResult AS [Actual Result]
    , @dateTimeOffsetMinMaxDiffTicks AS [Expected Result]
UNION ALL
SELECT 'Date Difference in Ticks Test (Max, Min)' AS Test
    , CASE 
        WHEN @dateDiffTicksMaxMinResult = @dateTimeOffsetMaxMinDiffTicks
            THEN 'Pass'
        ELSE 'Fail'
        END AS [Test Status]
    , @dateTimeOffsetMaxValue AS [Starting Date]
    , @dateTimeOffsetMinValue AS [Ending Date]
    , @dateDiffTicksMaxMinResult AS [Actual Result]
    , @dateTimeOffsetMaxMinDiffTicks AS [Expected Result]

PRINT 'Tests Complete.'
GO
--- END Test Harness ---
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.