본문 바로가기
Unity/Advanced

유니티 시간 (DateTime)

by 노튜 2025. 2. 21.
728x90
반응형

1. Time 그리고 DateTime 

Time 클래스는 유니티 앱이 실행되는 동안의 시간과 관련된 값을 제공한다면, DateTime은 현실 시간을 기반으로 한다. 

Time 클래스는 애플리케이션이 실행되는 시간과 관련된 기능을 구현할 때에는 매우 유용하다. 예를 들어, 스테이지 클리어 시간을 측정할 경우이다. DateTime을 사용할 경우에는 일시정지한 시간을 배제하는 코드를 추가적으로 구현해야 한다. 하지만 Time.timeScale에 영향을 받는 Time.timeSinceLevelLoad의 값을 사용하여 일시정지한 시간을 배제하고 시간을 측정할 수 있기 때문이다.

DateTime 구조체는 현실 날짜 및 시간을 기반으로한 시간 기능에 유용하다. 예를 들어, 현재 시간, 일일 로그인 보상 등을 예로 들 수 있다. 사용자가 종료하고 다시 접속하였을 때 시간에 따른 추가적인 보상을 제공하는 기능들도 DateTime 구조체를 사용하면 쉽게 구현이 가능하다. 

2. Time 클래스

유니티는 시간과 관련된 Time 클래스를 제공한다. Time 클래스는 게임이나 앱이 실행되는 동안 시간의 흐름을 측정할 수 있도록 숫자 값을 제공하는 클래스이다.

Time 클래스는 다음 글에서 다룬다.

2025.02.18 - [유니티/중급] - 유니티 시간(Time)

 

유니티 시간(Time)

1. Time유니티 프로젝트를 진행하다 보면 시간과 관련된 기능을 구현하는 경우가 생긴다. 재사용 대기시간(Cooldown), 지속시간(Duration time) 등을 예로 들 수 있다. 유니티는 시간과 관련된 Time 클래스

notyu.tistory.com

반응형

2. DateTime 구조체

일반적으로 날짜와 시간으로 표현된 시간의 한 순간을 나타내는 구조체이다 [1]. DateTime은 현실 시간을 기반으로 한 날짜 및 시간과 관련된 숫자 값을 제공한다.

DateTime은 System namespace를 사용한다.

using System;

2.1. 현재 시간

  • DateTime.Now : 사용자가 있는 현지 시간의 현재 시간
  • DateTime.UtcNow : 협정 세계 시간의 현재 시간

DateTime.Now는 한국시간을 표현하면 DateTime.UtcNow보다 9시간 빠른 시간으로 표시된다 [2]. DateTime.Now는 사용자가 이용 중인 지역의 시간이 표시되며, DateTime.UtcNow는 지역에 상관없이 동일한 시간을 나타낸다. 만약 모든 지역의 이용자가 하나의 서버에 접속하고, 동일한 시간을 공유한다면 DateTime.UtcNow을 사용한다.

 

※DateTime.Now를 사용하는 경우 시스템의 가령 디바이스의 지역을 변경하여, 그 시간 값의 차이를 이용하는 문제가 발생할 수 있다. 시간을 사용하여 기능을 구현할 때에는 DateTime.UtcNow를 사용하는 것을 추천한다.

 

DateTime.UtcNow and DateTime.Now

 

using System;
using UnityEngine;

public class TestTime : MonoBehaviour
{
   //Update is called once per frame
   void Update()
   {
     Debug.Log("UTC:" + DateTime.UtcNow + "//Local:" + DateTime.Now);
   }
}

 

2.2. TimeSpan 구조체

시간 간격을 나타내는 구조체이다 [3]. 두 날짜 사이의 차이를 계산하는데 사용한다. 

TimeSpan은 System namespace를 등록해야한다.

using System;

 

DateTime의 속성값 Now와 UtcNow의 Ticks값을 사용하여 시간 차이를 계산한다. 

long tick = DateTime.UtcNow.Ticks - DateTime.Now.Ticks;

 

두 시간 사이의 차이를 계산한 값을 TimeSpan 구조체를 사용하여 시간의 값을 계산한다.

TimeSpan timeSpan = new TimeSpan(tick);

 

다음은 TimeSpan 개체의 속성 값이다. 

TimeSpan의 값을 일, 시간, 분, 초, 밀리초 만큼의 차이를 나타낸다. 

  • Days : 두 날짜 사이의 일수의 차이를 나타낸다.
  • Hours : 두 날짜 사이의 일수를 제외한 시간의 차이를 나타낸다.
  • Minutes : 두 날짜 사이의 일수, 시간을 제외한 분의 차이를 나타낸다.
  • Seconds : 두 날짜 사이의 일수, 시간, 분을 제외한 초의 차이를 나타낸다.
  • Milliseconds : 두 날짜 사이의 일수, 시간, 분, 초를 제외한 밀리초의 차이를 나타낸다.

TimeSpan의 값을 일, 시간, 분, 초, 밀리초의 각각의 차이로 계산하여 표시한다. 

  • TotalDays :  두 날짜 사이의 차이를 일수로 나타낸다.  
  • TotalHours : 두 날짜 사이의 차이를 시간으로 나타낸다.
  • TotalMinutes : 두 날짜 사이의 차이를 분으로 나타낸다.
  • TotalSeconds : 두 날짜 사이의 차이를 초로 나타낸다.
  • TotalMiliseconds : 두 날짜 사이의 차이를 밀리초로 나타낸다.

TimeSpawn : DateTime.UtcNow - DateTime.Utc

 

using System;
using UnityEngine;

public class TestTime : MonoBehaviour
{
  //Update is called once per frame
  void Update()
  {
     long time = DateTime.UtcNow.Ticks - DateTime.Now.Ticks;
     TimeSpan timeSpan = new TimeSpan(time);
     Debug.Log(timeSpan);
  }
}

 

2.3 DateTime 변환

2.3.1 DateTime을 long 형으로 변환

아래의 함수를 사용하여 long형 값으로 변환한다.

long time = DateTime.ToFileTimeUtc(); // UtcNow 
long time = DateTime.ToFileTime();  // Now

 

2.3.2 long형을 DateTime으로 변환 

아래의 함수를 사용하여 long 형을 DateTime으로 변환한다.

DateTime dateTime = DateTime.FromFileTimeUtc(long time);
DateTime dateTime = DateTime.FromFileTime(long time);

 

2.4 시간 저장 및 불러오기

DateTime은 시간을 저장 및 불러오기가 가능하도록 long형으로 변환하여 주는 기능을 지원한다.

long형 값을 PlayerPrefs나 Json을 사용하여 저장 및 불러오기 한다.  

728x90

2.5 시간 예제

시간을 저장하고 불러오는 예제이다.

게임이나 앱이 종료되면 시간을 저장하고, 다시 실행하면 종료한 시간만큼을 계산하여 보상을 지급하도록 한다.  

 

using UnitySystem;
using UnityEngine;

public class ElapsedTime : MonoBehaviour
{
   static readonly string key = "LogOutTime";
   static readonly double rewardSecondRate = 1.0f; 
   // Awake is called once
   void Awake()
   {
      LoadLogOutTime();
   }
   
   void LoadLogOutTime()
   {
      if(PlayerPrefs.HasKey(key) == false)
         return;
      
      string strLogOutTime = PlayerPrefs.GetString(key);
      long logOutTime = long.Parse(strLogOutTime);
      double elapsedTime = CalElapsedTime(logOutTime);
      double rewardCount = Math.Floor(elapsedTime / rewardSecondRate);
      Debug.Log("RewardCount:" + Conver.ToInt32(rewardCount));
   }
   
   void SaveLogOutTime()
   {
      long logOutTime = DateTime.UtcNow.ToFileTimeUtc();
      PlayerPrefs.SetString(key, logOutTime.ToString());
   }
   
   double CalElapsedTime(long _logOutTime)
   {
      DateTime logOutTime = DateTime.FromFileTimeUtc(_logOutTime);
      long tick = Date.UtcNow.Ticks - logOutTime.Ticks;
      TimeSpan timeSpan = new TimeSpan(tick);
      return timeSpan.TotalSeconds;
   }
   
   // OnApplicationpause is called
   void OnApplicationPause(bool pauseStatus)
   {
      if (pauseStatus)
      {
         SaveLogOutTime();
      }
   }
   // OnApplicationQuit is called
   void OnApplicationQuit()
   {
#if UNITY_EDITOR
      SaveLogOutTime();
#endif    
   }
}

 

 

References

[1] DateTime

https://learn.microsoft.com/ko-kr/dotnet/api/system.datetime?view=net-8.0

[2] DateTime Now and UTC

https://learn.microsoft.com/ko-kr/power-platform/power-fx/reference/function-now-today-istoday

[3] TimeSpan

https://learn.microsoft.com/ko-kr/dotnet/api/system.timespan?view=net-8.0

728x90
반응형