1. معرفی بسته زمان و تاریخ

بسته time در زبان Go یک کتابخانه قدرتمند است که به مدیریت زمان و تاریخ می‌پردازد. این بسته امکان نمایش، تجزیه و تجزیه‌نمایی زمان را فراهم می‌کند، که برای حل مسائل محاسبات زمان و تاریخی که در توسعه روزانه رو به رو می‌شوند، بسیار مناسب است. شما می‌توانید از این بسته برای به دست آوردن زمان فعلی، کنترل زمان و تاریخ، مقایسه زمان، تجزیه و فرمت‌بندی زمان و ... استفاده کنید.

2. توضیح مفصل درباره نوع زمان

در زبان Go، نوع Time یک لحظه یا نقطه‌ای در زمان را نمایان می‌کند. شما می‌توانید از تابع time.Now() برای به دست آوردن زمان فعلی استفاده کنید. در ادامه یک مثال ساده برای نشان دادن نحوه اعلان و مقدمه متغیر نوع Time آورده شده است:

package main

import (
    "fmt"
    "time"
)

func main() {
    currentTime := time.Now()   // به دست آوردن زمان فعلی
    fmt.Printf("Current Time: %v\n", currentTime)
    
    // زمان سفارشی
    customTime := time.Date(2022, time.December, 31, 23, 59, 59, 0, time.UTC)
    fmt.Printf("Custom Time: %v\n", customTime)
}

در کد فوق، time.Now() برای به دست آوردن زمان فعلی و تابع time.Date() برای مقدمه کردن یک زمان خاص استفاده شده است. این تابع با گرفتن پارامترهای سال، ماه، روز، ساعت، دقیقه، ثانیه و نانوثانیه، همچنین یک منطقه‌ی زمانی، فراخوانی می‌شود.

3. فرمت‌بندی و تجزیه‌کردن

3.1. فرمت‌بندی زمان و تاریخ

فرمت‌بندی زمان و تاریخ به معنای نمایش زمان نوع Time به صورت خوانا برای انسان است. در Go، شما می‌توانید از متد Format نوع Time برای فرمت‌بندی زمان استفاده کنید. Go از یک الگوی مرجع خاص (2006-01-02 15:04:05) برای راهنمایی در مورد چگونگی فرمت‌بندی زمان استفاده می‌کند. در ادامه مثالی آمده است:

package main

import (
    "fmt"
    "time"
)

func main() {
    currentTime := time.Now()

    // فرمت‌بندی زمان به صورت "YYYY-MM-DD"
    fmt.Println("تاریخ فرمت‌بندی شده:", currentTime.Format("2006-01-02"))
    
    // فرمت‌بندی زمان به صورت "YYYY-MM-DD hh:mm:ss"
    fmt.Println("تاریخ و زمان فرمت‌بندی شده:", currentTime.Format("2006-01-02 15:04:05"))
    
    // فرمت‌بندی زمان به صورت "MM/DD/YY hh:mm:ss PM"
    fmt.Println("فرمت‌بندی با الگوهای مختلف:", currentTime.Format("01/02/06 03:04:05 PM"))
}

توجه کنید که فرمت‌بندی باید از زمان مرجع تولد Go (2 ژانویه 2006، 15:04:05 UTC) به عنوان زمان مرجع و فرمت استفاده کند.

3.2. تجزیه‌کردن رشته‌های زمان و تاریخ

تجزیه‌کردن رشته‌های زمان و تاریخ به فرایند تبدیل رشته‌های زمان و تاریخ حرفه‌ای به نوع Time است. در Go، شما می‌توانید از متد time.Parse برای تجزیه‌کردن رشته‌ها استفاده کنید. در ادامه یک مثال ساده آورده شده است:

package main

import (
    "fmt"
    "time"
)

func main() {
    timeString := "2022-12-31 23:59:59"

    // تجزیه‌کردن رشته‌ی زمان مطابق
    parsedTime, err := time.Parse("2006-01-02 15:04:05", timeString)
    if err != nil {
        fmt.Println("خطا در تجزیه‌کردن زمان:", err)
    } else {
        fmt.Printf("زمان تجزیه‌شده: %v\n", parsedTime)
    }
}

در تابع time.Parse، پارامتر اول رشته الگو، که فرمت رشته زمان ورودی را مشخص می‌کند، و پارامتر دوم رشته‌ی زمانی که می‌خواهید تجزیه ‌کنید، می‌باشد.

4. عملیات زمان

در برنامه نویسی، انجام عملیات زمان یک نیاز رایج است، سهیم که در ثبت لاگ، برنامه‌ریزی رویداد یا نمایش زمان در رابط کاربری، انجام عملیات جمع و تفریق زمان ممکن است ضروری باشد.

4.1. افزودن و کاهش زمان

در بسته‌ی time زبان Go، نوع Time امکانات Add و Sub را برای انجام عملیات افزودن و کاهش زمان ارائه می‌دهد.

  • از متد Add برای افزودن زمان استفاده می‌شود:
package main

import (
	"fmt"
	"time"
)

func main() {
	// زمان فعلی
	now := time.Now()

	// افزودن ۲ ساعت
	twoHoursLater := now.Add(2 * time.Hour)

	fmt.Println("زمان فعلی:", now)
	fmt.Println("دو ساعت بعد:", twoHoursLater)
}

در کد فوق، ثابت time.Hour برای نشان دادن دو ساعت استفاده شده و با استفاده از متد Add به متغیر now اضافه می‌شود.

  • از متد Sub برای محاسبه تفاوت زمان استفاده می‌شود:
// زمان فعلی
now := time.Now()

// دو ساعت قبل از زمان فعلی
twoHoursBefore := now.Add(-2 * time.Hour)

fmt.Println("زمان فعلی:", now)
fmt.Println("دو ساعت قبل:", twoHoursBefore)

// با استفاده از متد Sub تفاوت زمان را محاسبه می‌کنیم
duration := now.Sub(twoHoursBefore)

fmt.Println("تفاوت زمان دو زمان:", duration)

در مثال کد فوق، -2 * time.Hour برای نشان دادن دو ساعت قبل از زمان فعلی استفاده شده و متد Sub برای محاسبه تفاوت زمان بین دو نمونه‌ی Time استفاده می‌شود که منجر به نوع time.Duration می‌شود.

4.2. محاسبه‌ی فاصله‌ی زمانی

محاسبه‌ی تفاوت بین دو نقطه‌ی زمانی وظیفه‌ی متداری مشترک دیگری است، مثلاً محاسبه‌ی فاصله‌ی زمانی بین دو رویداد. در زبان Go، این کار با استفاده از متد Sub به راحتی قابل انجام است.

package main

import (
	"fmt"
	"time"
)

func main() {
	startTime := time.Date(2023, 1, 1, 10, 0, 0, 0, time.UTC)
	endTime := time.Date(2023, 1, 1, 12, 30, 0, 0, time.UTC)

// محاسبه‌ی تفاوت زمانی
duration := endTime.Sub(startTime)

fmt.Printf("مدت زمان رویداد %v بوده است.\n", duration)
}

در این قسمت کد، دو نقطه‌ی زمانی startTime و endTime ایجاد شده و با استفاده از متد Sub، تفاوت زمانی duration بین آن‌ها به‌دست آمده است.

5. تبدیل برچسب زمان به نوع زمان و بالعکس

برچسب زمان اندازه‌گیری زمان از یک نقطه خاص در زمان است (معمولاً تعداد ثانیه‌ها از تاریخ Unix) و به عنوان یک روش دیگر برای نمایش یک نقطه زمانی عمل می‌کند.

  • تبدیل یک برچسب زمان به نوع Time:
package main

import (
	"fmt"
	"time"
)

func main() {
// دریافت برچسب زمان فعلی
timestamp := time.Now().Unix()

// تبدیل برچسب زمان به نوع زمان
tm := time.Unix(timestamp, 0)

fmt.Println("برچسب زمان فعلی:", timestamp)
fmt.Println("نوع زمان متناظر:", tm)
}

تابع Unix با گرفتن یک پارامتر نشان دهنده‌ی ثانیه‌ها و دیگری نشان دهنده‌ی نانوثانیه‌ها، برای تبدیل یک برچسب زمانی به نوع time.Time استفاده می‌شود.

  • گرفتن برچسب زمان از نوع Time:
// گرفتن زمان فعلی
now := time.Now()

// تبدیل نوع زمان به برچسب زمان
timestamp := now.Unix()

fmt.Println("زمان فعلی:", now)
fmt.Println("برچسب زمان متناظر:", timestamp)

در این کد، متد Unix برای گرفتن برچسب زمان متناظر با نوع Time استفاده می‌شود که بسیار مفید برای ذخیره یا ارسال اطلاعات زمانی است.

6. پردازش منطقه‌زمانی

پردازش منطقه‌زمانی برای ساخت سیستم‌هایی که بر مختلف مناطق جغرافیایی گسترده می‌شوند، اساسی است. بسته‌ی time در Go به شما امکان می‌دهد با مناطق‌زمانی مختلف کار کنید.

  • ایجاد زمان برای یک منطقه‌زمانی خاص:
package main

import (
	"fmt"
	"time"
)

func main() {
	// بارگذاری منطقه‌زمانی
	loc, _ := time.LoadLocation("Europe/Paris")

	// ایجاد زمان با استفاده از منطقه‌زمانی خاص
	now := time.Now().In(loc)

	fmt.Println("زمان پاریس:", now)
}

کد فوق منطقه‌زمانی "Europe/Paris" را با استفاده از تابع LoadLocation بارگذاری می‌کند و سپس زمان فعلی را در پاریس با استفاده از متد In ایجاد می‌کند.

  • تبدیل مناطق‌زمانی:
// ایجاد زمان در UTC
utcTime := time.Date(2023, 1, 1, 12, 0, 0, 0, time.UTC)

// بارگذاری منطقه‌زمانی مقصد
nyLoc, _ := time.LoadLocation("America/New_York")

// تبدیل زمان UTC به زمان نیویورک
nyTime := utcTime.In(nyLoc)

fmt.Println("زمان UTC:", utcTime)
fmt.Println("زمان نیویورک:", nyTime)

کد فوق نحوه تبدیل زمان UTC به زمان نیویورک را نشان می‌دهد.

7. تایمرها و تیکرها

بسته‌ی time تایمرها و تیکرها را فراهم می‌کند که می‌توان از آن‌ها برای وظایفی که اجرای دوره‌ای نیاز دارند، استفاده کرد.

  • استفاده از Timer:
package main

import (
	"fmt"
	"time"
)

func main() {
	// ایجاد یک تایمر تنظیم شده برای فعال‌شدن پس از 2 ثانیه
	timer := time.NewTimer(2 * time.Second)

	// هنگامی که تایمر فعال می‌شود، زمان فعلی را به timer.C ارسال می‌کند
	<-timer.C

	fmt.Println("تایمر فعال شد")
}

در این کد، یک تایمر تنظیم شده برای فعال‌شدن پس از 2 ثانیه ایجاد می‌شود، و <-timer.C برای انتظار فعال شدن آن استفاده می‌شود.

  • استفاده از Ticker برای اجرای تکراری:
// ایجاد یک تیکر تنظیم شده برای فعال‌شدن هر 1 ثانیه
ticker := time.NewTicker(1 * time.Second)

for i := 0; i < 5; i++ {
	// دریافت مقادیر از طریق کانال
	<-ticker.C
	fmt.Println("تیکر فعال شد", i+1, "بار")
}

// توقف تیکر
ticker.Stop()

کد فوق نحوه ایجاد یک تیکر که هر 1 ثانیه فعال می‌شود را نشان می‌دهد و سپس پس از فعال شدن 5 بار، آن را متوقف می‌کند.

تایمرها و تیکرها ابزارهای قدرتمندی برای عملیات مربوط به زمان هستند که به شما کمک می‌کنند تا منطق کنترل دقیق زمان را ایجاد کنید.