简体   繁体   中英

How can I convert a string to DateTime in Unity?

I'm currently working on a virtual pet game, and I need help to solve this issue, as fast as possible. I'm trying to get the timeSpan of between now and the last time I've played, and the script doesn't continue after the part of the timeSpan (Mentioned below the script, including the main question). The Script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bird : MonoBehaviour {

    [SerializeField]
    private int _hunger;
    [SerializeField]
    private int _happiness;
    [SerializeField]
    private string _name;

    private bool _servertime;
    private int _clickCount;

    DateTime timeSpan4;
    void Start()
    {
        print("Then: " + PlayerPrefs.GetString("then"));
        print("getStringTime(): " + getStringTime());
        print("TimeOfDay: " + DateTime.Now.TimeOfDay);
        print("DateTime now: " + DateTime.Now);
        //PlayerPrefs.SetString("then", "09 / 12 / 2019 20:50:0");
        updateStatus();
        //if (!PlayerPrefs.HasKey("name"))
        //    PlayerPrefs.SetString("name", "Bird");
        _name = PlayerPrefs.GetString("name");
    }

    void Update()
    {
        GetComponent<Animator>().SetBool("Fly", gameObject.transform.position.y > -2.3);

        if (Input.GetMouseButtonUp(0))
        {
            //Debug.Log("Clicked");
            Vector2 v = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
            RaycastHit2D hit = Physics2D.Raycast(Camera.main.ScreenToWorldPoint(v), Vector2.zero);
            if (hit)
            {
                //Debug.Log(hit.transform.gameObject.name);
                if(hit.transform.gameObject.tag == "Birb")
                {
                    _clickCount++;
                    if(_clickCount >= 3)
                    {
                        _clickCount = 0;
                        updateHappiness(5);
                        GetComponent<Rigidbody2D>().AddForce(new Vector2(0, 1000));
                    }
                }
            }
        }
    }

    public void updateStatus()
    {
        print("Updating Status...");
        if (!PlayerPrefs.HasKey("_hunger"))
        {
            _hunger = 100;
            PlayerPrefs.SetInt("_hunger", _hunger);
        }
        else
        {
            _hunger = PlayerPrefs.GetInt("_hunger");
        }

        if (!PlayerPrefs.HasKey("_happiness"))
        {
            _happiness = 100;
            PlayerPrefs.SetInt("_happiness", _happiness);
        }
        else
        {
            _happiness = PlayerPrefs.GetInt("_happiness");
        }

        if (!PlayerPrefs.HasKey("then"))
            PlayerPrefs.SetString("then", getStringTime());

        TimeSpan ts = getTimeSpan();

        _hunger -= (int)(ts.TotalHours * 2);
        if (_hunger < 0)
        {
            _hunger = 0;
            PlayerPrefs.SetInt("_hunger", _hunger);
        }
        if (_hunger > 100)
        {
            _hunger = 100;
            PlayerPrefs.SetInt("_hunger", _hunger);
            print("hunger is bigger than 100!");
        }

        _happiness -= (int)((100 - _hunger) * (ts.TotalHours / 5));
        if (_happiness < 0)
        {
            _happiness = 0;
            PlayerPrefs.SetInt("_happiness", _happiness);
        }
        if (_happiness > 100)
        {
            _happiness = 0;
            PlayerPrefs.SetInt("_happiness", _happiness);
        }

        //Debug.Log(getTimeSpan().ToString());
        //Debug.Log(getTimeSpan().TotalHours);

        if (_servertime)
            updateServer();
        else
            InvokeRepeating("saveBird", 0f, 2f);
    }

    void updateServer()
    {

    }
    void updateDevice()
    {
        PlayerPrefs.SetString("then", getStringTime());
    }

    TimeSpan getTimeSpan()
    {
        if (_servertime)
            return new TimeSpan();
        else
            return DateTime.Now - Convert.ToDateTime(PlayerPrefs.GetString("then"));
    }

    string getStringTime()
    {
        DateTime now = DateTime.Now;
        return now.Day + "-" + now.Month + "-" + now.Year + " " + now.Hour + ":" + now.Minute + ":" + now.Second;
    }
    public int hunger
    {
        get { return _hunger; }
        set { _hunger = value; }
    }
    public int happiness
    {
        get { return _happiness; }
        set { _happiness = value; }
    }

    public string BName
    {
        get { return _name; }
        set { _name = value; }
    }

    public void updateHappiness(int i)
    {
        happiness += i;
        if (happiness > 100)
            happiness = 100;
    }
    public void saveBird()
    {
        if (!_servertime)
            updateDevice();
        PlayerPrefs.SetInt("_hunger", _hunger);
        PlayerPrefs.SetInt("_happiness", _happiness);
    }
}

The problem is in line 134 ( return DateTime.Now - Convert.ToDateTime(PlayerPrefs.GetString("then")); ), it prints FormatException: String was not recognized as a valid DateTime. , and because of that the script doesn't continue after that part. How can I convert the string "then" to a DateTime so it won't error?

The exact format for loading a date from a string depends on a lot of factors. One of the most important being the locale .

That being said you're a lot safer if you use DateTimes string formatting methods instead of saving it by hand.

You can change your getStringTime() to rely on ToString and save that:

string getStringTime() {
  return DateTime.Now.ToString();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM