সি # তে একটি নির্দিষ্ট টাইম জোনে একটি ডেটটাইম তৈরি করা হচ্ছে


162

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

পরীক্ষায় আমার কোনও স্থানীয় সময় অঞ্চলে ডেটটাইম অবজেক্ট তৈরি করতে সক্ষম হওয়া দরকার যাতে পরীক্ষা চালানো লোকেরা যেখানেই থাকুক না কেন সফলতার সাথে এটি করতে পারে।

ডেটটাইম নির্মাণকারীর কাছ থেকে আমি যা দেখতে পাচ্ছি তা থেকে আমি টাইমজোনকে স্থানীয় সময় অঞ্চল, ইউটিসি টাইমজোন বা নির্দিষ্ট না করে সেট করতে পারি।

আমি কীভাবে পিএসটি-র মতো নির্দিষ্ট সময় অঞ্চল নিয়ে একটি ডেটটাইম তৈরি করব?


সম্পর্কিত প্রশ্ন - stackoverflow.com/questions/2532729/…
ওডে

উত্তর:


216

জনের উত্তর টাইমজোন সম্পর্কে আলোচনা করে তবে আমি পরিবর্তে টাইমজোনআইএনফো ব্যবহার করার পরামর্শ দেব ।

ব্যক্তিগতভাবে আমি জিনিসগুলি যেখানে ইউটিসিতে রাখা সম্ভব সেখানে রাখা পছন্দ করি (কমপক্ষে অতীতের জন্য; ভবিষ্যতে ইউটিসি সংরক্ষণের সম্ভাব্য সমস্যা রয়েছে ), তাই আমি এই জাতীয় কাঠামোর পরামর্শ দেব:

public struct DateTimeWithZone
{
    private readonly DateTime utcDateTime;
    private readonly TimeZoneInfo timeZone;

    public DateTimeWithZone(DateTime dateTime, TimeZoneInfo timeZone)
    {
        var dateTimeUnspec = DateTime.SpecifyKind(dateTime, DateTimeKind.Unspecified);
        utcDateTime = TimeZoneInfo.ConvertTimeToUtc(dateTimeUnspec, timeZone); 
        this.timeZone = timeZone;
    }

    public DateTime UniversalTime { get { return utcDateTime; } }

    public TimeZoneInfo TimeZone { get { return timeZone; } }

    public DateTime LocalTime
    { 
        get 
        { 
            return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); 
        }
    }        
}

বিষয়গুলি আরও পরিষ্কার করার জন্য আপনি "টাইমজোন" নামগুলি "টাইমজোনআইএনফো" তে পরিবর্তন করতে চাইতে পারেন - আমি নিজে ব্রেফার নাম পছন্দ করি।


5
আমি কোনও সমতুল্য এসকিউএল সার্ভারের নির্মাণ সম্পর্কে জানি না, আমি ভয় করি। আমি সময় কলের নামটি একটি কলাম হিসাবে এবং অন্য কলামে ইউটিসি মান রাখার পরামর্শ দেব। এগুলি আলাদাভাবে আনুন এবং তারপরে আপনি মোটামুটি সহজেই দৃষ্টান্তগুলি তৈরি করতে পারেন।
জন স্কিটি

2
তারিখটাইম এবং টাইমজোনইনফো গ্রহণকারী কনস্ট্রাক্টরের প্রত্যাশিত ব্যবহার সম্পর্কে নিশ্চিত নন, তবে আপনি যে তারিখটি.টম.উইনভার্সালটাইম () পদ্ধতিটি কল করছেন তাতে আমি সন্দেহ করি যে আপনি এটি স্থানীয় সময়ে "সম্ভবত" হতে অনুমান করছেন। সেক্ষেত্রে, আমি মনে করি আপনি সত্যিই পাস-ইন টাইমজোনইনফোটি এটি ইউটিসি তে রূপান্তর করতে ব্যবহার করবেন কারণ তারা আপনাকে বলছেন যে এটি সেই সময় অঞ্চলে থাকার কথা।
আইডিজিপোজেবল

2
@ ক্রিসমোসচিনি: এই মুহুর্তে আপনি কেবল নিজের আইডি স্কিম উদ্ভাবন করছেন - এমন একটি স্কিম যা বিশ্বের আর কেউ ব্যবহার করে না। আমি শিল্প-মানক অঞ্চলের সাথে থাকব, ধন্যবাদ। (উদাহরণস্বরূপ, "ইউরোপ / লন্ডন" কীভাবে অর্থহীন তা দেখা শক্ত))
জন স্কিটি

2
@ ক্রিসমোসচিনি: তার পরে আলাদা উদাহরণ: সিএসটি। এটি কি ইউটিসি -5 বা ইউটিসি -6? আইএসটি সম্পর্কে - আপনার ডাটাবেসে ইস্রায়েল, ভারত বা আয়ারল্যান্ড কীভাবে? (এবং আপনি যদি এখনই অফসেটটি জানেন তবেও একই সংক্ষেপণ পর্যবেক্ষণ করা বিভিন্ন দেশ বিভিন্ন সময়ে পরিবর্তিত হতে পারে So সুতরাং কোন প্রকৃত সময় অঞ্চলটি বোঝায় তা সম্পর্কে এখনও অস্পষ্টতা রয়েছে Time সময় অঞ্চল! = অফসেট)) আপনার ক্ষেত্রে ফিরে যাওয়া: আপনি দাবি করেন সংক্ষিপ্ত বিবরণ ব্যবহার করে আপনার সমস্যার সমাধান করে। শিল্পের স্ট্যান্ডার্ড টাইম জোন আইডি ব্যবহার করা কীভাবে খারাপ হবে?
জন স্কিটি

6
@ ক্রিসমোচিনি: আচ্ছা আমি অস্পষ্ট সংক্ষিপ্তসারগুলির পরিবর্তে শিল্প-মানের, দ্ব্যর্থহীন জোনিনফোর আইডি ব্যবহারের পরামর্শ দেব। এটি কার গ্রন্থাগারটি পছন্দ করা উচিত তা নয় - লাইব্রেরির লেখকত্ব আসলেই কোনও সমস্যা নয়। কেউ যদি সনাক্তকারী একটি ভাল পছন্দ সঙ্গে অন্য লাইব্রেরি ব্যবহার করতে চান , এটি ঠিক আছে। একটা সময় জোন শনাক্তকারীর পছন্দ যদিও একটি গুরুত্বপূর্ণ এক, এবং আমি মনে করি এটা খুবই গুরুত্বপূর্ণ যে পাঠকদের সচেতন থাকবেন বর্ণমালা হয় হয় , দ্ব্যর্থক হিসাবে আমি ভারতের উদাহরণ দেখানো গেছেন।
জন স্কিটি 20'13

54

ডেটটাইমঅফসেট কাঠামোটি ঠিক এই ধরণের ব্যবহারের জন্য তৈরি হয়েছিল।

দেখুন: http://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx

নির্দিষ্ট সময় অঞ্চল দিয়ে একটি ডেটটাইম অফসেট অবজেক্ট তৈরির উদাহরণ এখানে রয়েছে:

DateTimeOffset do1 = new DateTimeOffset(2008, 8, 22, 1, 0, 0, new TimeSpan(-5, 0, 0));


1
ধন্যবাদ, এটি সম্পাদন করার জন্য এটি একটি ভাল উপায়। আপনি আপনার সময়সীমার মধ্যে ডেটটাইম অফসেট অবজেক্টটি পাওয়ার পরে আপনি নিজের তৈরির জন্য একটি ইউটিসি সময় পেতে .UtcDateTime বৈশিষ্ট্যটি ব্যবহার করতে পারেন। আপনি যদি আপনার তারিখগুলি ইউটিসিতে সংরক্ষণ করেন, তবে প্রতিটি ব্যবহারকারীর জন্য স্থানীয় সময়ে তাদের রূপান্তর করা কোনও বড় বিষয় নয় :)
রেডথ

2
আমি মনে করি না যে এটি ডাইটলাইট সেভিংসের সময়টিকে সঠিকভাবে পরিচালনা করে যেহেতু কিছু টাইম অঞ্চলগুলি এটি সম্মান করে অন্যরা না করে। এছাড়াও "যে দিন" ডিএসটি শুরু / শেষ হয়, সেই দিনের অংশগুলি বন্ধ থাকবে।
ক্রোকুসেক 21

14
পাঠ। ডিএসটি একটি নির্দিষ্ট সময় অঞ্চলের একটি নিয়ম। ডেটটাইমঅফসেট কোনও সময় অঞ্চলের সাথে সম্পর্কিত নয়। কোনও ইউটিসি অফসেট মান যেমন -5 এর সাথে টাইম জোনের সাথে গুলিয়ে ফেলবেন না। এটি কোনও সময় অঞ্চল নয়, এটি অফসেট। একই অফসেটটি প্রায়শই অনেক সময় অঞ্চল দ্বারা ভাগ করা হয়, তাই এটি কোনও সময় অঞ্চলকে উল্লেখ করার জন্য একটি দ্ব্যর্থক উপায়। যেহেতু ডেটটাইমঅফসেট কোনও টাইমজোন নয়, অফসেটের সাথে সম্পর্কিত, এটি সম্ভবত ডিএসটি বিধি প্রয়োগ করতে পারে না। তাই ডেটটাইম অফসেট কাঠামো ব্যতীত বছরের প্রতিটি একদিন 3am সকাল 3 টা হবে (যেমন এটির আওয়ারস এবং টাইমঅফডে বৈশিষ্ট্যগুলিতে)।
ট্রায়ঙ্কো

আপনি ডেটটাইমঅফসেটের লোকালডেটটাইম সম্পত্তিটি দেখলে আপনি কোথায় বিভ্রান্ত হতে পারেন is এই সম্পত্তিটি কোনও ডেটটাইম অফসেট নয়, এটি একটি ডেটটাইম উদাহরণ যার प्रकार হ'ল ডেটটাইমকিন্ড.লোকাল। এই উদাহরণটি টাইম জোনের সাথে সম্পর্কিত ... স্থানীয় সিস্টেমের সময় অঞ্চলটি যাই হোক না কেন। এই সম্পত্তি দিনের আলোর সঞ্চয় প্রতিফলিত করবে।
ট্রায়ঙ্কো

4
সুতরাং, ডেটটাইম অফসেটের সাথে আসল সমস্যাটি হ'ল এতে যথেষ্ট তথ্য অন্তর্ভুক্ত নেই। এটিতে কোনও অফসেট অন্তর্ভুক্ত থাকে, সময় অঞ্চল নয়। অফসেটটি একাধিক সময় অঞ্চলগুলির সাথে অস্পষ্ট।
ট্রায়ঙ্কো

41

এখানে অন্যান্য উত্তরগুলি দরকারী তবে তারা কীভাবে প্রশান্ত মহাসাগরটি অ্যাক্সেস করবেন তা কভার করে না - এখানে আপনি যান:

public static DateTime GmtToPacific(DateTime dateTime)
{
    return TimeZoneInfo.ConvertTimeFromUtc(dateTime,
        TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time"));
}

আশ্চর্যের সাথে যথেষ্ট, যদিও "প্যাসিফিক স্ট্যান্ডার্ড টাইম" এর অর্থ সাধারণত "প্যাসিফিক দিবালোকের সময়" থেকে আলাদা কিছু অর্থ হয়, এক্ষেত্রে এটি সাধারণত প্রশান্ত মহাসাগরীয় সময়কে বোঝায়। আসলে, আপনি যদি FindSystemTimeZoneByIdএটি আনতে ব্যবহার করেন তবে উপলভ্য বৈশিষ্ট্যগুলির মধ্যে একটি হ'ল এটি আপনাকে বোঝায় যে সেই সময় অঞ্চলটি বর্তমানে দিবালোকের সঞ্চয়ে রয়েছে কিনা।

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

https://github.com/b9chris/TimeZoneInfoLib.Net

এটি উইন্ডোজের বাইরে কাজ করবে না (উদাহরণস্বরূপ লিনাক্সে মনো) যেহেতু সময়ের তালিকা উইন্ডোজ রেজিস্ট্রি থেকে আসে: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\

এর নীচে আপনি কীগুলি (রেজিস্ট্রি এডিটরটিতে ফোল্ডার আইকনগুলি) পাবেন; এই কীগুলির নামগুলি আপনি যা পাস করেছেন তা FindSystemTimeZoneById। লিনাক্সে আপনাকে টাইমজোন সংজ্ঞাগুলির একটি পৃথক লিনাক্স-মানক সেট ব্যবহার করতে হবে, যা আমি পর্যাপ্তভাবে অনুসন্ধান করে দেখিনি।


1
অতিরিক্ত রূপে কনভার্টটাইমবাইসিস্টেমটাইমজোনআইডি () যেমন: টাইমজোনআইফোন.ক্যানভার্টটাইমবিসিস্টেমটাইমজোনআইড (তারিখটাইম.উত্তকনো, "সেন্ট্রাল স্ট্যান্ডার্ড টাইম")
ব্রেন্ট

উইন্ডোতে টাইমজোন আইডি তালিকাতে এই উত্তরটি দেখতে পাবেন: stackoverflow.com/a/24460750/4573839
yu yang jian

7

এক্সটেনশন পদ্ধতিতে আমি জনের স্কিটের উত্তরটি কিছুটা পরিবর্তিত করেছি । এটি মোহন হিসাবে অজুরে উপর কাজ করে।

public static class DateTimeWithZone
{

private static readonly TimeZoneInfo timeZone;

static DateTimeWithZone()
{
//I added web.config <add key="CurrentTimeZoneId" value="Central Europe Standard Time" />
//You can add value directly into function.
    timeZone = TimeZoneInfo.FindSystemTimeZoneById(ConfigurationManager.AppSettings["CurrentTimeZoneId"]);
}


public static DateTime LocalTime(this DateTime t)
{
     return TimeZoneInfo.ConvertTime(t, timeZone);   
}
}

2

আপনাকে এটির জন্য একটি কাস্টম অবজেক্ট তৈরি করতে হবে। আপনার কাস্টম অবজেক্টে দুটি মান থাকবে:

ইতিমধ্যে কোনও সিএলআর-সরবরাহিত ডেটা টাইপ রয়েছে কিনা তা নিশ্চিত নন, তবে কমপক্ষে টাইমজোন উপাদানটি ইতিমধ্যে উপলব্ধ।


2

আমি জোন স্কিটির উত্তরটি পছন্দ করি তবে একটি জিনিস যুক্ত করতে চাই। আমি নিশ্চিত নই যে জন সর্বদা স্থানীয় সময় অঞ্চলে কর্টরটি পাস করার আশা করছিল। তবে আমি এটি স্থানীয় ক্ষেত্রে অন্য কিছু হতে পারে এমন ক্ষেত্রে ব্যবহার করতে চাই।

আমি একটি ডাটাবেস থেকে মানগুলি পড়ছি, এবং আমি জানি যে সেই ডেটাবেসটি কী টাইমজোন। সুতরাং, কোডারে, আমি ডাটাবেসের টাইমজোনটি পাস করব। তবে আমি স্থানীয় সময় মান চাই। জনের লোকালটাইম স্থানীয় সময় অঞ্চল তারিখে রূপান্তরিত আসল তারিখটি ফেরায় না। এটি আসল টাইমজোনতে রূপান্তরিত তারিখটি ফেরত দেয় (যা কিছু আপনি কোডরের মধ্যে দিয়েছিলেন)।

আমি মনে করি এই সম্পত্তির নামগুলি এটি পরিষ্কার করে দিয়েছে ...

public DateTime TimeInOriginalZone { get { return TimeZoneInfo.ConvertTime(utcDateTime, timeZone); } }
public DateTime TimeInLocalZone    { get { return TimeZoneInfo.ConvertTime(utcDateTime, TimeZoneInfo.Local); } }
public DateTime TimeInSpecificZone(TimeZoneInfo tz)
{
    return TimeZoneInfo.ConvertTime(utcDateTime, tz);
}

0

ব্যবহার সময়ের অঞ্চলগুলোকে বর্গ এটা সহজ সময় অঞ্চল নির্দিষ্ট তারিখ তৈরি করে তোলে।

TimeZoneInfo.ConvertTime(DateTime.Now, TimeZoneInfo.FindSystemTimeZoneById(TimeZones.Paris.Id));

1
দুঃখিত, তবে এটি এখানে Asp .NET কোর 2.2 তে উপলভ্য নয়, ভিএস2017 আমাকে একটি আউটলুক নুগেট প্যাকেজ ইনস্টল করার পরামর্শ দিচ্ছে।
মাচাদো

উদাহরণ => টাইমজোনআইএনফো.কনভার্টটাইম (ডেটটাইম.নাউ, টাইমজোনআইফোন.ফাইন্ডসিস্টেমটাইমজোনবিআইআইডি ("প্যাসিফিক স্ট্যান্ডার্ড টাইম"))
এজেড_
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.